xref: /freebsd/sbin/setkey/test-pfkey.c (revision 069ac184)
1 /*	$KAME: test-pfkey.c,v 1.4 2000/06/07 00:29:14 itojun Exp $	*/
2 
3 /*-
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the project nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/socket.h>
37 #include <net/route.h>
38 #include <net/pfkeyv2.h>
39 #include <netinet/in.h>
40 #include <netipsec/keydb.h>
41 #include <netipsec/key_var.h>
42 #include <netipsec/key_debug.h>
43 
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <limits.h>
47 #include <string.h>
48 #include <ctype.h>
49 #include <unistd.h>
50 #include <errno.h>
51 #include <netdb.h>
52 
53 u_char m_buf[BUFSIZ];
54 u_int m_len;
55 char *pname;
56 
57 void Usage(void);
58 int sendkeymsg(void);
59 void key_setsadbmsg(u_int);
60 void key_setsadbsens(void);
61 void key_setsadbprop(void);
62 void key_setsadbid(u_int, caddr_t);
63 void key_setsadblft(u_int, u_int);
64 void key_setspirange(void);
65 void key_setsadbkey(u_int, caddr_t);
66 void key_setsadbsa(void);
67 void key_setsadbaddr(u_int, u_int, caddr_t);
68 void key_setsadbextbuf(caddr_t, int, caddr_t, int, caddr_t, int);
69 
70 void
71 Usage()
72 {
73 	printf("Usage:\t%s number\n", pname);
74 	exit(0);
75 }
76 
77 int
78 main(ac, av)
79 	int ac;
80 	char **av;
81 {
82 	pname = *av;
83 
84 	if (ac == 1) Usage();
85 
86 	key_setsadbmsg(atoi(*(av+1)));
87 	sendkeymsg();
88 
89 	exit(0);
90 }
91 
92 /* %%% */
93 int
94 sendkeymsg()
95 {
96 	u_char rbuf[1024 * 32];	/* XXX: Enough ? Should I do MSG_PEEK ? */
97 	int so, len;
98 
99 	if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) {
100 		perror("socket(PF_KEY)");
101 		goto end;
102 	}
103 #if 0
104     {
105 #include <sys/time.h>
106 	struct timeval tv;
107 	tv.tv_sec = 1;
108 	tv.tv_usec = 0;
109 	if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
110 		perror("setsockopt");
111 		goto end;
112 	}
113     }
114 #endif
115 
116 	pfkey_sadump((struct sadb_msg *)m_buf);
117 
118 	if ((len = send(so, m_buf, m_len, 0)) < 0) {
119 		perror("send");
120 		goto end;
121 	}
122 
123 	if ((len = recv(so, rbuf, sizeof(rbuf), 0)) < 0) {
124 		perror("recv");
125 		goto end;
126 	}
127 
128 	pfkey_sadump((struct sadb_msg *)rbuf);
129 
130 end:
131 	(void)close(so);
132 	return(0);
133 }
134 
135 void
136 key_setsadbmsg(type)
137 	u_int type;
138 {
139 	struct sadb_msg m_msg;
140 
141 	memset(&m_msg, 0, sizeof(m_msg));
142 	m_msg.sadb_msg_version = PF_KEY_V2;
143 	m_msg.sadb_msg_type = type;
144 	m_msg.sadb_msg_errno = 0;
145 	m_msg.sadb_msg_satype = SADB_SATYPE_ESP;
146 #if 0
147 	m_msg.sadb_msg_reserved = 0;
148 #endif
149 	m_msg.sadb_msg_seq = 0;
150 	m_msg.sadb_msg_pid = getpid();
151 
152 	m_len = sizeof(struct sadb_msg);
153 	memcpy(m_buf, &m_msg, m_len);
154 
155 	switch (type) {
156 	case SADB_GETSPI:
157 		/*<base, address(SD), SPI range>*/
158 		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "10.0.3.4");
159 		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "127.0.0.1");
160 		key_setspirange();
161 		/*<base, SA(*), address(SD)>*/
162 		break;
163 
164 	case SADB_ADD:
165 		/* <base, SA, (lifetime(HSC),) address(SD), (address(P),)
166 		   key(AE), (identity(SD),) (sensitivity)> */
167 		key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1");
168 	case SADB_UPDATE:
169 		key_setsadbsa();
170 		key_setsadblft(SADB_EXT_LIFETIME_HARD, 10);
171 		key_setsadblft(SADB_EXT_LIFETIME_SOFT, 5);
172 		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1");
173 		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4");
174 		/* XXX key_setsadbkey(SADB_EXT_KEY_AUTH, "abcde"); */
175 		key_setsadbkey(SADB_EXT_KEY_AUTH, "1234567812345678");
176 		key_setsadbkey(SADB_EXT_KEY_ENCRYPT, "12345678");
177 		key_setsadbid(SADB_EXT_IDENTITY_SRC, "hoge1234@hoge.com");
178 		key_setsadbid(SADB_EXT_IDENTITY_DST, "hage5678@hage.net");
179 		key_setsadbsens();
180 		/* <base, SA, (lifetime(HSC),) address(SD), (address(P),)
181 		  (identity(SD),) (sensitivity)> */
182 		break;
183 
184 	case SADB_DELETE:
185 		/* <base, SA(*), address(SDP)> */
186 		key_setsadbsa();
187 		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1");
188 		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4");
189 		key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1");
190 		/* <base, SA(*), address(SDP)> */
191 		break;
192 
193 	case SADB_GET:
194 		/* <base, SA(*), address(SDP)> */
195 		key_setsadbsa();
196 		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1");
197 		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4");
198 		key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1");
199 		/* <base, SA, (lifetime(HSC),) address(SD), (address(P),)
200 		   key(AE), (identity(SD),) (sensitivity)> */
201 		break;
202 
203 	case SADB_ACQUIRE:
204 		/* <base, address(SD), (address(P),) (identity(SD),)
205 		   (sensitivity,) proposal> */
206 		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1");
207 		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4");
208 		key_setsadbaddr(SADB_EXT_ADDRESS_PROXY, AF_INET6, "3ffe::1");
209 		key_setsadbid(SADB_EXT_IDENTITY_SRC, "hoge1234@hoge.com");
210 		key_setsadbid(SADB_EXT_IDENTITY_DST, "hage5678@hage.net");
211 		key_setsadbsens();
212 		key_setsadbprop();
213 		/* <base, address(SD), (address(P),) (identity(SD),)
214 		   (sensitivity,) proposal> */
215 		break;
216 
217 	case SADB_REGISTER:
218 		/* <base> */
219 		/* <base, supported> */
220 		break;
221 
222 	case SADB_EXPIRE:
223 	case SADB_FLUSH:
224 		break;
225 
226 	case SADB_DUMP:
227 		break;
228 
229 	case SADB_X_PROMISC:
230 		/* <base> */
231 		/* <base, base(, others)> */
232 		break;
233 
234 	case SADB_X_PCHANGE:
235 		break;
236 
237 	/* for SPD management */
238 	case SADB_X_SPDFLUSH:
239 	case SADB_X_SPDDUMP:
240 		break;
241 
242 	case SADB_X_SPDADD:
243 #if 0
244 	    {
245 		struct sadb_x_policy m_policy;
246 
247 		m_policy.sadb_x_policy_len = PFKEY_UNIT64(sizeof(m_policy));
248 		m_policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
249 		m_policy.sadb_x_policy_type = SADB_X_PL_IPSEC;
250 		m_policy.sadb_x_policy_esp_trans = 1;
251 		m_policy.sadb_x_policy_ah_trans = 2;
252 		m_policy.sadb_x_policy_esp_network = 3;
253 		m_policy.sadb_x_policy_ah_network = 4;
254 		m_policy.sadb_x_policy_reserved = 0;
255 
256 		memcpy(m_buf + m_len, &m_policy, sizeof(struct sadb_x_policy));
257 		m_len += sizeof(struct sadb_x_policy);
258 	    }
259 #endif
260 
261 	case SADB_X_SPDDELETE:
262 		key_setsadbaddr(SADB_EXT_ADDRESS_SRC, AF_INET, "192.168.1.1");
263 		key_setsadbaddr(SADB_EXT_ADDRESS_DST, AF_INET, "10.0.3.4");
264 		break;
265 	}
266 
267 	((struct sadb_msg *)m_buf)->sadb_msg_len = PFKEY_UNIT64(m_len);
268 
269 	return;
270 }
271 
272 void
273 key_setsadbsens()
274 {
275 	struct sadb_sens m_sens;
276 	u_char buf[64];
277 	u_int s, i, slen, ilen, len;
278 
279 	/* make sens & integ */
280 	s = htonl(0x01234567);
281 	i = htonl(0x89abcdef);
282 	slen = sizeof(s);
283 	ilen = sizeof(i);
284 	memcpy(buf, &s, slen);
285 	memcpy(buf + slen, &i, ilen);
286 
287 	len = sizeof(m_sens) + PFKEY_ALIGN8(slen) + PFKEY_ALIGN8(ilen);
288 	m_sens.sadb_sens_len = PFKEY_UNIT64(len);
289 	m_sens.sadb_sens_exttype = SADB_EXT_SENSITIVITY;
290 	m_sens.sadb_sens_dpd = 1;
291 	m_sens.sadb_sens_sens_level = 2;
292 	m_sens.sadb_sens_sens_len = PFKEY_ALIGN8(slen);
293 	m_sens.sadb_sens_integ_level = 3;
294 	m_sens.sadb_sens_integ_len = PFKEY_ALIGN8(ilen);
295 	m_sens.sadb_sens_reserved = 0;
296 
297 	key_setsadbextbuf(m_buf, m_len,
298 			(caddr_t)&m_sens, sizeof(struct sadb_sens),
299 			buf, slen + ilen);
300 	m_len += len;
301 
302 	return;
303 }
304 
305 void
306 key_setsadbprop()
307 {
308 	struct sadb_prop m_prop;
309 	struct sadb_comb *m_comb;
310 	u_char buf[256];
311 	u_int len = sizeof(m_prop) + sizeof(m_comb) * 2;
312 
313 	/* make prop & comb */
314 	m_prop.sadb_prop_len = PFKEY_UNIT64(len);
315 	m_prop.sadb_prop_exttype = SADB_EXT_PROPOSAL;
316 	m_prop.sadb_prop_replay = 0;
317 	m_prop.sadb_prop_reserved[0] = 0;
318 	m_prop.sadb_prop_reserved[1] = 0;
319 	m_prop.sadb_prop_reserved[2] = 0;
320 
321 	/* the 1st is ESP AES-GCM-16 */
322 	m_comb = (struct sadb_comb *)buf;
323 	m_comb->sadb_comb_auth = SADB_AALG_NONE;
324 	m_comb->sadb_comb_encrypt = SADB_X_EALG_AESGCM16;
325 	m_comb->sadb_comb_flags = 0;
326 	m_comb->sadb_comb_auth_minbits = 0;
327 	m_comb->sadb_comb_auth_maxbits = 0;
328 	m_comb->sadb_comb_encrypt_minbits = 128;
329 	m_comb->sadb_comb_encrypt_maxbits = 256;
330 	m_comb->sadb_comb_reserved = 0;
331 	m_comb->sadb_comb_soft_allocations = 0;
332 	m_comb->sadb_comb_hard_allocations = 0;
333 	m_comb->sadb_comb_soft_bytes = 0;
334 	m_comb->sadb_comb_hard_bytes = 0;
335 	m_comb->sadb_comb_soft_addtime = 0;
336 	m_comb->sadb_comb_hard_addtime = 0;
337 	m_comb->sadb_comb_soft_usetime = 0;
338 	m_comb->sadb_comb_hard_usetime = 0;
339 
340 	/* the 2nd is ESP AES-CBC and AH HMAC-SHA2-256 */
341 	m_comb = (struct sadb_comb *)(buf + sizeof(*m_comb));
342 	m_comb->sadb_comb_auth = SADB_X_AALG_SHA2_256;
343 	m_comb->sadb_comb_encrypt = SADB_X_EALG_RIJNDAELCBC;
344 	m_comb->sadb_comb_flags = 0;
345 	m_comb->sadb_comb_auth_minbits = 256;
346 	m_comb->sadb_comb_auth_maxbits = 256;
347 	m_comb->sadb_comb_encrypt_minbits = 128;
348 	m_comb->sadb_comb_encrypt_maxbits = 256;
349 	m_comb->sadb_comb_reserved = 0;
350 	m_comb->sadb_comb_soft_allocations = 0;
351 	m_comb->sadb_comb_hard_allocations = 0;
352 	m_comb->sadb_comb_soft_bytes = 0;
353 	m_comb->sadb_comb_hard_bytes = 0;
354 	m_comb->sadb_comb_soft_addtime = 0;
355 	m_comb->sadb_comb_hard_addtime = 0;
356 	m_comb->sadb_comb_soft_usetime = 0;
357 	m_comb->sadb_comb_hard_usetime = 0;
358 
359 	key_setsadbextbuf(m_buf, m_len,
360 			(caddr_t)&m_prop, sizeof(struct sadb_prop),
361 			buf, sizeof(*m_comb) * 2);
362 	m_len += len;
363 
364 	return;
365 }
366 
367 void
368 key_setsadbid(ext, str)
369 	u_int ext;
370 	caddr_t str;
371 {
372 	struct sadb_ident m_id;
373 	u_int idlen = strlen(str), len;
374 
375 	len = sizeof(m_id) + PFKEY_ALIGN8(idlen);
376 	m_id.sadb_ident_len = PFKEY_UNIT64(len);
377 	m_id.sadb_ident_exttype = ext;
378 	m_id.sadb_ident_type = SADB_IDENTTYPE_USERFQDN;
379 	m_id.sadb_ident_reserved = 0;
380 	m_id.sadb_ident_id = getpid();
381 
382 	key_setsadbextbuf(m_buf, m_len,
383 			(caddr_t)&m_id, sizeof(struct sadb_ident),
384 			str, idlen);
385 	m_len += len;
386 
387 	return;
388 }
389 
390 void
391 key_setsadblft(ext, time)
392 	u_int ext, time;
393 {
394 	struct sadb_lifetime m_lft;
395 
396 	m_lft.sadb_lifetime_len = PFKEY_UNIT64(sizeof(m_lft));
397 	m_lft.sadb_lifetime_exttype = ext;
398 	m_lft.sadb_lifetime_allocations = 0x2;
399 	m_lft.sadb_lifetime_bytes = 0x1000;
400 	m_lft.sadb_lifetime_addtime = time;
401 	m_lft.sadb_lifetime_usetime = 0x0020;
402 
403 	memcpy(m_buf + m_len, &m_lft, sizeof(struct sadb_lifetime));
404 	m_len += sizeof(struct sadb_lifetime);
405 
406 	return;
407 }
408 
409 void
410 key_setspirange()
411 {
412 	struct sadb_spirange m_spi;
413 
414 	m_spi.sadb_spirange_len = PFKEY_UNIT64(sizeof(m_spi));
415 	m_spi.sadb_spirange_exttype = SADB_EXT_SPIRANGE;
416 	m_spi.sadb_spirange_min = 0x00001000;
417 	m_spi.sadb_spirange_max = 0x00002000;
418 	m_spi.sadb_spirange_reserved = 0;
419 
420 	memcpy(m_buf + m_len, &m_spi, sizeof(struct sadb_spirange));
421 	m_len += sizeof(struct sadb_spirange);
422 
423 	return;
424 }
425 
426 void
427 key_setsadbkey(ext, str)
428 	u_int ext;
429 	caddr_t str;
430 {
431 	struct sadb_key m_key;
432 	u_int keylen = strlen(str);
433 	u_int len;
434 
435 	len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen);
436 	m_key.sadb_key_len = PFKEY_UNIT64(len);
437 	m_key.sadb_key_exttype = ext;
438 	m_key.sadb_key_bits = keylen * 8;
439 	m_key.sadb_key_reserved = 0;
440 
441 	key_setsadbextbuf(m_buf, m_len,
442 			(caddr_t)&m_key, sizeof(struct sadb_key),
443 			str, keylen);
444 	m_len += len;
445 
446 	return;
447 }
448 
449 void
450 key_setsadbsa()
451 {
452 	struct sadb_sa m_sa;
453 
454 	m_sa.sadb_sa_len = PFKEY_UNIT64(sizeof(struct sadb_sa));
455 	m_sa.sadb_sa_exttype = SADB_EXT_SA;
456 	m_sa.sadb_sa_spi = htonl(0x12345678);
457 	m_sa.sadb_sa_replay = 4;
458 	m_sa.sadb_sa_state = 0;
459 	m_sa.sadb_sa_auth = SADB_AALG_NONE;
460 	m_sa.sadb_sa_encrypt = SADB_X_EALG_AESGCM16;
461 	m_sa.sadb_sa_flags = 0;
462 
463 	memcpy(m_buf + m_len, &m_sa, sizeof(struct sadb_sa));
464 	m_len += sizeof(struct sadb_sa);
465 
466 	return;
467 }
468 
469 void
470 key_setsadbaddr(ext, af, str)
471 	u_int ext, af;
472 	caddr_t str;
473 {
474 	struct sadb_address m_addr;
475 	u_int len;
476 	struct addrinfo hints, *res;
477 	const char *serv;
478 	int plen;
479 
480 	switch (af) {
481 	case AF_INET:
482 		plen = sizeof(struct in_addr) << 3;
483 		break;
484 	case AF_INET6:
485 		plen = sizeof(struct in6_addr) << 3;
486 		break;
487 	default:
488 		/* XXX bark */
489 		exit(1);
490 	}
491 
492 	/* make sockaddr buffer */
493 	memset(&hints, 0, sizeof(hints));
494 	hints.ai_family = af;
495 	hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
496 	hints.ai_flags = AI_NUMERICHOST;
497 	serv = (ext == SADB_EXT_ADDRESS_PROXY ? "0" : "4660");	/*0x1234*/
498 	if (getaddrinfo(str, serv, &hints, &res) != 0 || res->ai_next) {
499 		/* XXX bark */
500 		exit(1);
501 	}
502 
503 	len = sizeof(struct sadb_address) + PFKEY_ALIGN8(res->ai_addrlen);
504 	m_addr.sadb_address_len = PFKEY_UNIT64(len);
505 	m_addr.sadb_address_exttype = ext;
506 	m_addr.sadb_address_proto =
507 		(ext == SADB_EXT_ADDRESS_PROXY ? 0 : IPPROTO_TCP);
508 	m_addr.sadb_address_prefixlen = plen;
509 	m_addr.sadb_address_reserved = 0;
510 
511 	key_setsadbextbuf(m_buf, m_len,
512 			(caddr_t)&m_addr, sizeof(struct sadb_address),
513 			(caddr_t)res->ai_addr, res->ai_addrlen);
514 	m_len += len;
515 
516 	freeaddrinfo(res);
517 
518 	return;
519 }
520 
521 void
522 key_setsadbextbuf(dst, off, ebuf, elen, vbuf, vlen)
523 	caddr_t dst, ebuf, vbuf;
524 	int off, elen, vlen;
525 {
526 	memset(dst + off, 0, elen + vlen);
527 	memcpy(dst + off, (caddr_t)ebuf, elen);
528 	memcpy(dst + off + elen, vbuf, vlen);
529 
530 	return;
531 }
532 
533