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