xref: /openbsd-src/regress/usr.bin/ssh/unittests/kex/test_proposal.c (revision 5be191007b7524c9061a81c513c53886ce7e3f6f)
1*5be19100Sdtucker /* 	$OpenBSD: test_proposal.c,v 1.2 2023/03/06 12:15:47 dtucker Exp $ */
2fe2f27c1Sdjm /*
3fe2f27c1Sdjm  * Regress test KEX
4fe2f27c1Sdjm  *
5fe2f27c1Sdjm  * Placed in the public domain
6fe2f27c1Sdjm  */
7fe2f27c1Sdjm 
8fe2f27c1Sdjm #include <sys/types.h>
9fe2f27c1Sdjm #include <signal.h>
10fe2f27c1Sdjm #include <stdio.h>
11fe2f27c1Sdjm #include <stdint.h>
12fe2f27c1Sdjm #include <stdlib.h>
13fe2f27c1Sdjm #include <string.h>
14fe2f27c1Sdjm 
15fe2f27c1Sdjm #include "test_helper.h"
16fe2f27c1Sdjm 
17*5be19100Sdtucker #include "cipher.h"
18fe2f27c1Sdjm #include "compat.h"
19fe2f27c1Sdjm #include "ssherr.h"
20fe2f27c1Sdjm #include "sshbuf.h"
21fe2f27c1Sdjm #include "kex.h"
22*5be19100Sdtucker #include "myproposal.h"
23fe2f27c1Sdjm #include "packet.h"
24fe2f27c1Sdjm #include "xmalloc.h"
25fe2f27c1Sdjm 
26*5be19100Sdtucker void kex_proposal_tests(void);
27*5be19100Sdtucker void kex_proposal_populate_tests(void);
28fe2f27c1Sdjm 
29fe2f27c1Sdjm #define CURVE25519 "curve25519-sha256@libssh.org"
30fe2f27c1Sdjm #define DHGEX1 "diffie-hellman-group-exchange-sha1"
31fe2f27c1Sdjm #define DHGEX256 "diffie-hellman-group-exchange-sha256"
32fe2f27c1Sdjm #define KEXALGOS CURVE25519","DHGEX256","DHGEX1
33fe2f27c1Sdjm void
kex_proposal_tests(void)34*5be19100Sdtucker kex_proposal_tests(void)
35fe2f27c1Sdjm {
36fe2f27c1Sdjm 	size_t i;
37fe2f27c1Sdjm 	struct ssh ssh;
38fe2f27c1Sdjm 	char *result, *out, *in;
39fe2f27c1Sdjm 	struct {
40fe2f27c1Sdjm 		char *in;	/* TODO: make this const */
41fe2f27c1Sdjm 		char *out;
42fe2f27c1Sdjm 		int compat;
43fe2f27c1Sdjm 	} tests[] = {
44fe2f27c1Sdjm 		{ KEXALGOS, KEXALGOS, 0},
45fe2f27c1Sdjm 		{ KEXALGOS, DHGEX256","DHGEX1, SSH_BUG_CURVE25519PAD },
46fe2f27c1Sdjm 		{ KEXALGOS, CURVE25519, SSH_OLD_DHGEX },
47fe2f27c1Sdjm 		{ "a,"KEXALGOS, "a", SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX },
48fe2f27c1Sdjm 		/* TODO: enable once compat_kex_proposal doesn't fatal() */
49fe2f27c1Sdjm 		/* { KEXALGOS, "", SSH_BUG_CURVE25519PAD|SSH_OLD_DHGEX }, */
50fe2f27c1Sdjm 	};
51fe2f27c1Sdjm 
52fe2f27c1Sdjm 	TEST_START("compat_kex_proposal");
53fe2f27c1Sdjm 	for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
54fe2f27c1Sdjm 		ssh.compat = tests[i].compat;
55fe2f27c1Sdjm 		/* match entire string */
56fe2f27c1Sdjm 		result = compat_kex_proposal(&ssh, tests[i].in);
57fe2f27c1Sdjm 		ASSERT_STRING_EQ(result, tests[i].out);
58fe2f27c1Sdjm 		free(result);
59fe2f27c1Sdjm 		/* match at end */
60fe2f27c1Sdjm 		in = kex_names_cat("a", tests[i].in);
61fe2f27c1Sdjm 		out = kex_names_cat("a", tests[i].out);
62fe2f27c1Sdjm 		result = compat_kex_proposal(&ssh, in);
63fe2f27c1Sdjm 		ASSERT_STRING_EQ(result, out);
64fe2f27c1Sdjm 		free(result); free(in); free(out);
65fe2f27c1Sdjm 		/* match at start */
66fe2f27c1Sdjm 		in = kex_names_cat(tests[i].in, "a");
67fe2f27c1Sdjm 		out = kex_names_cat(tests[i].out, "a");
68fe2f27c1Sdjm 		result = compat_kex_proposal(&ssh, in);
69fe2f27c1Sdjm 		ASSERT_STRING_EQ(result, out);
70fe2f27c1Sdjm 		free(result); free(in); free(out);
71fe2f27c1Sdjm 		/* match in middle */
72fe2f27c1Sdjm 		xasprintf(&in, "a,%s,b", tests[i].in);
73fe2f27c1Sdjm 		if (*(tests[i].out) == '\0')
74fe2f27c1Sdjm 			out = xstrdup("a,b");
75fe2f27c1Sdjm 		else
76fe2f27c1Sdjm 			xasprintf(&out, "a,%s,b", tests[i].out);
77fe2f27c1Sdjm 		result = compat_kex_proposal(&ssh, in);
78fe2f27c1Sdjm 		ASSERT_STRING_EQ(result, out);
79fe2f27c1Sdjm 		free(result); free(in); free(out);
80fe2f27c1Sdjm 	}
81fe2f27c1Sdjm 	TEST_DONE();
82fe2f27c1Sdjm }
83*5be19100Sdtucker 
84*5be19100Sdtucker void
kex_proposal_populate_tests(void)85*5be19100Sdtucker kex_proposal_populate_tests(void)
86*5be19100Sdtucker {
87*5be19100Sdtucker 	char *prop[PROPOSAL_MAX], *kexalgs, *ciphers, *macs, *hkalgs;
88*5be19100Sdtucker 	const char *comp = compression_alg_list(0);
89*5be19100Sdtucker 	int i;
90*5be19100Sdtucker 	struct ssh ssh;
91*5be19100Sdtucker 	struct kex kex;
92*5be19100Sdtucker 
93*5be19100Sdtucker 	kexalgs = kex_alg_list(',');
94*5be19100Sdtucker 	ciphers = cipher_alg_list(',', 0);
95*5be19100Sdtucker 	macs = mac_alg_list(',');
96*5be19100Sdtucker 	hkalgs = kex_alg_list(',');
97*5be19100Sdtucker 
98*5be19100Sdtucker 	ssh.kex = &kex;
99*5be19100Sdtucker 	TEST_START("compat_kex_proposal_populate");
100*5be19100Sdtucker 	for (i = 0; i <= 1; i++) {
101*5be19100Sdtucker 		kex.server = i;
102*5be19100Sdtucker 		for (ssh.compat = 0; ssh.compat < 0x40000000; ) {
103*5be19100Sdtucker 			kex_proposal_populate_entries(&ssh, prop, NULL, NULL,
104*5be19100Sdtucker 			    NULL, NULL, NULL);
105*5be19100Sdtucker 			kex_proposal_free_entries(prop);
106*5be19100Sdtucker 			kex_proposal_populate_entries(&ssh, prop, kexalgs,
107*5be19100Sdtucker 			    ciphers, macs, hkalgs, comp);
108*5be19100Sdtucker 			kex_proposal_free_entries(prop);
109*5be19100Sdtucker 			if (ssh.compat == 0)
110*5be19100Sdtucker 				ssh.compat = 1;
111*5be19100Sdtucker 			else
112*5be19100Sdtucker 				ssh.compat <<= 1;
113*5be19100Sdtucker 		}
114*5be19100Sdtucker 	}
115*5be19100Sdtucker 
116*5be19100Sdtucker 	free(kexalgs);
117*5be19100Sdtucker 	free(ciphers);
118*5be19100Sdtucker 	free(macs);
119*5be19100Sdtucker 	free(hkalgs);
120*5be19100Sdtucker }
121