4 * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 2001 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: keycreate.c,v 1.18 2009/09/01 00:22:25 jinmei Exp */
28 #include <isc/base64.h>
29 #include <isc/entropy.h>
33 #include <isc/sockaddr.h>
34 #include <isc/socket.h>
36 #include <isc/timer.h>
39 #include <dns/dispatch.h>
40 #include <dns/fixedname.h>
41 #include <dns/keyvalues.h>
42 #include <dns/message.h>
44 #include <dns/request.h>
45 #include <dns/result.h>
50 #include <dst/result.h>
52 #define CHECK(str, x) { \
53 if ((x) != ISC_R_SUCCESS) { \
54 fprintf(stderr, "I:%s: %s\n", (str), isc_result_totext(x)); \
59 #define RUNCHECK(x) RUNTIME_CHECK((x) == ISC_R_SUCCESS)
64 static dst_key_t
*ourkey
;
65 static isc_mem_t
*mctx
;
66 static dns_tsigkey_t
*tsigkey
, *initialkey
;
67 static dns_tsig_keyring_t
*ring
;
68 static unsigned char noncedata
[16];
69 static isc_buffer_t nonce
;
70 static dns_requestmgr_t
*requestmgr
;
71 static const char *ownername_str
= ".";
74 recvquery(isc_task_t
*task
, isc_event_t
*event
) {
75 dns_requestevent_t
*reqev
= (dns_requestevent_t
*)event
;
77 dns_message_t
*query
, *response
;
79 isc_buffer_t keynamebuf
;
84 REQUIRE(reqev
!= NULL
);
86 if (reqev
->result
!= ISC_R_SUCCESS
) {
87 fprintf(stderr
, "I:request event result: %s\n",
88 isc_result_totext(reqev
->result
));
92 query
= reqev
->ev_arg
;
95 result
= dns_message_create(mctx
, DNS_MESSAGE_INTENTPARSE
, &response
);
96 CHECK("dns_message_create", result
);
98 result
= dns_request_getresponse(reqev
->request
, response
,
99 DNS_MESSAGEPARSE_PRESERVEORDER
);
100 CHECK("dns_request_getresponse", result
);
102 if (response
->rcode
!= dns_rcode_noerror
) {
103 result
= ISC_RESULTCLASS_DNSRCODE
+ response
->rcode
;
104 fprintf(stderr
, "I:response rcode: %s\n",
105 isc_result_totext(result
));
109 result
= dns_tkey_processdhresponse(query
, response
, ourkey
, &nonce
,
111 CHECK("dns_tkey_processdhresponse", result
);
114 * Yes, this is a hack.
116 isc_buffer_init(&keynamebuf
, keyname
, sizeof(keyname
));
117 result
= dst_key_buildfilename(tsigkey
->key
, 0, "", &keynamebuf
);
118 CHECK("dst_key_buildfilename", result
);
119 printf("%.*s\n", (int)isc_buffer_usedlength(&keynamebuf
),
120 (char *)isc_buffer_base(&keynamebuf
));
121 type
= DST_TYPE_PRIVATE
| DST_TYPE_PUBLIC
| DST_TYPE_KEY
;
122 result
= dst_key_tofile(tsigkey
->key
, type
, "");
123 CHECK("dst_key_tofile", result
);
125 dns_message_destroy(&query
);
126 dns_message_destroy(&response
);
127 dns_request_destroy(&reqev
->request
);
128 isc_event_free(&event
);
134 sendquery(isc_task_t
*task
, isc_event_t
*event
) {
135 struct in_addr inaddr
;
136 isc_sockaddr_t address
;
139 dns_fixedname_t keyname
;
140 dns_fixedname_t ownername
;
141 isc_buffer_t namestr
, keybuf
;
142 unsigned char keydata
[9];
143 dns_message_t
*query
;
144 dns_request_t
*request
;
145 static char keystr
[] = "0123456789ab";
147 isc_event_free(&event
);
149 result
= ISC_R_FAILURE
;
150 if (inet_pton(AF_INET
, "10.53.0.1", &inaddr
) != 1)
151 CHECK("inet_pton", result
);
152 isc_sockaddr_fromin(&address
, &inaddr
, PORT
);
154 dns_fixedname_init(&keyname
);
155 isc_buffer_init(&namestr
, "tkeytest.", 9);
156 isc_buffer_add(&namestr
, 9);
157 result
= dns_name_fromtext(dns_fixedname_name(&keyname
), &namestr
,
159 CHECK("dns_name_fromtext", result
);
161 dns_fixedname_init(&ownername
);
162 isc_buffer_init(&namestr
, ownername_str
, strlen(ownername_str
));
163 isc_buffer_add(&namestr
, strlen(ownername_str
));
164 result
= dns_name_fromtext(dns_fixedname_name(&ownername
), &namestr
,
166 CHECK("dns_name_fromtext", result
);
168 isc_buffer_init(&keybuf
, keydata
, 9);
169 result
= isc_base64_decodestring(keystr
, &keybuf
);
170 CHECK("isc_base64_decodestring", result
);
172 isc_buffer_usedregion(&keybuf
, &r
);
175 result
= dns_tsigkey_create(dns_fixedname_name(&keyname
),
176 DNS_TSIG_HMACMD5_NAME
,
177 isc_buffer_base(&keybuf
),
178 isc_buffer_usedlength(&keybuf
),
179 ISC_FALSE
, NULL
, 0, 0, mctx
, ring
,
181 CHECK("dns_tsigkey_create", result
);
184 result
= dns_message_create(mctx
, DNS_MESSAGE_INTENTRENDER
, &query
);
185 CHECK("dns_message_create", result
);
187 result
= dns_tkey_builddhquery(query
, ourkey
,
188 dns_fixedname_name(&ownername
),
189 DNS_TSIG_HMACMD5_NAME
, &nonce
, 3600);
190 CHECK("dns_tkey_builddhquery", result
);
193 result
= dns_request_create(requestmgr
, query
, &address
,
194 0, initialkey
, TIMEOUT
, task
,
195 recvquery
, query
, &request
);
196 CHECK("dns_request_create", result
);
200 main(int argc
, char *argv
[]) {
202 isc_taskmgr_t
*taskmgr
;
203 isc_timermgr_t
*timermgr
;
204 isc_socketmgr_t
*socketmgr
;
206 unsigned int attrs
, attrmask
;
207 isc_sockaddr_t bind_any
;
208 dns_dispatchmgr_t
*dispatchmgr
;
209 dns_dispatch_t
*dispatchv4
;
214 isc_logconfig_t
*logconfig
;
219 RUNCHECK(isc_app_start());
222 fprintf(stderr
, "I:no DH key provided\n");
225 ourkeyname
= argv
[1];
228 ownername_str
= argv
[2];
230 dns_result_register();
233 RUNCHECK(isc_mem_create(0, 0, &mctx
));
236 RUNCHECK(isc_entropy_create(mctx
, &ectx
));
237 RUNCHECK(isc_entropy_createfilesource(ectx
, "random.data"));
238 RUNCHECK(isc_hash_create(mctx
, ectx
, DNS_NAME_MAXWIRE
));
242 RUNCHECK(isc_log_create(mctx
, &log
, &logconfig
));
244 RUNCHECK(dst_lib_init(mctx
, ectx
, ISC_ENTROPY_GOODONLY
));
247 RUNCHECK(isc_taskmgr_create(mctx
, 1, 0, &taskmgr
));
249 RUNCHECK(isc_task_create(taskmgr
, 0, &task
));
251 RUNCHECK(isc_timermgr_create(mctx
, &timermgr
));
253 RUNCHECK(isc_socketmgr_create(mctx
, &socketmgr
));
255 RUNCHECK(dns_dispatchmgr_create(mctx
, NULL
, &dispatchmgr
));
256 isc_sockaddr_any(&bind_any
);
257 attrs
= DNS_DISPATCHATTR_UDP
|
258 DNS_DISPATCHATTR_MAKEQUERY
|
259 DNS_DISPATCHATTR_IPV4
;
260 attrmask
= DNS_DISPATCHATTR_UDP
|
261 DNS_DISPATCHATTR_TCP
|
262 DNS_DISPATCHATTR_IPV4
|
263 DNS_DISPATCHATTR_IPV6
;
265 RUNCHECK(dns_dispatch_getudp(dispatchmgr
, socketmgr
, taskmgr
,
266 &bind_any
, 4096, 4, 2, 3, 5,
267 attrs
, attrmask
, &dispatchv4
));
269 RUNCHECK(dns_requestmgr_create(mctx
, timermgr
, socketmgr
, taskmgr
,
270 dispatchmgr
, dispatchv4
, NULL
,
274 RUNCHECK(dns_tsigkeyring_create(mctx
, &ring
));
276 RUNCHECK(dns_tkeyctx_create(mctx
, ectx
, &tctx
));
279 RUNCHECK(dns_view_create(mctx
, 0, "_test", &view
));
280 dns_view_setkeyring(view
, ring
);
283 RUNCHECK(isc_socket_create(socketmgr
, PF_INET
, isc_sockettype_udp
,
286 RUNCHECK(isc_app_onrun(mctx
, task
, sendquery
, NULL
));
289 type
= DST_TYPE_PUBLIC
| DST_TYPE_PRIVATE
| DST_TYPE_KEY
;
290 result
= dst_key_fromnamedfile(ourkeyname
, NULL
, type
, mctx
, &ourkey
);
291 CHECK("dst_key_fromnamedfile", result
);
293 isc_buffer_init(&nonce
, noncedata
, sizeof(noncedata
));
294 result
= isc_entropy_getdata(ectx
, noncedata
, sizeof(noncedata
),
295 NULL
, ISC_ENTROPY_BLOCKING
);
296 CHECK("isc_entropy_getdata", result
);
297 isc_buffer_add(&nonce
, sizeof(noncedata
));
301 dns_requestmgr_shutdown(requestmgr
);
302 dns_requestmgr_detach(&requestmgr
);
303 dns_dispatch_detach(&dispatchv4
);
304 dns_dispatchmgr_destroy(&dispatchmgr
);
305 isc_task_shutdown(task
);
306 isc_task_detach(&task
);
307 isc_taskmgr_destroy(&taskmgr
);
308 isc_socket_detach(&sock
);
309 isc_socketmgr_destroy(&socketmgr
);
310 isc_timermgr_destroy(&timermgr
);
312 dst_key_free(&ourkey
);
313 dns_tsigkey_detach(&initialkey
);
314 dns_tsigkey_detach(&tsigkey
);
316 dns_tkeyctx_destroy(&tctx
);
318 dns_view_detach(&view
);
320 isc_log_destroy(&log
);
324 isc_entropy_detach(&ectx
);
326 isc_mem_destroy(&mctx
);