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