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