1 #include "config.h"
2 
3 #define LIBSSH_STATIC
4 
5 #include "torture.h"
6 #include "torture_key.h"
7 #include "legacy.c"
8 
9 #define LIBSSH_RSA_TESTKEY "libssh_testkey.id_rsa"
10 #ifdef HAVE_DSA
11 #define LIBSSH_DSA_TESTKEY "libssh_testkey.id_dsa"
12 #endif
13 
setup_rsa_key(void ** state)14 static int setup_rsa_key(void **state)
15 {
16     ssh_session session;
17 
18     unlink(LIBSSH_RSA_TESTKEY);
19     unlink(LIBSSH_RSA_TESTKEY ".pub");
20 
21     torture_write_file(LIBSSH_RSA_TESTKEY,
22                        torture_get_testkey(SSH_KEYTYPE_RSA, 0));
23     torture_write_file(LIBSSH_RSA_TESTKEY ".pub",
24                        torture_get_testkey_pub(SSH_KEYTYPE_RSA));
25 
26     session = ssh_new();
27     *state = session;
28 
29     return 0;
30 }
31 
32 #ifdef HAVE_DSA
setup_dsa_key(void ** state)33 static int setup_dsa_key(void **state)
34 {
35     ssh_session session;
36 
37     unlink(LIBSSH_DSA_TESTKEY);
38     unlink(LIBSSH_DSA_TESTKEY ".pub");
39 
40     torture_write_file(LIBSSH_DSA_TESTKEY,
41                        torture_get_testkey(SSH_KEYTYPE_DSS, 0));
42     torture_write_file(LIBSSH_DSA_TESTKEY ".pub",
43                        torture_get_testkey_pub(SSH_KEYTYPE_DSS));
44 
45     session = ssh_new();
46     *state = session;
47 
48     return 0;
49 }
50 #endif
51 
setup_both_keys(void ** state)52 static int setup_both_keys(void **state) {
53     int rc;
54 
55     rc = setup_rsa_key(state);
56     if (rc != 0) {
57         return rc;
58     }
59 #ifdef HAVE_DSA
60     ssh_free(*state);
61 
62     rc = setup_dsa_key(state);
63 #endif
64 
65     return rc;
66 }
67 
setup_both_keys_passphrase(void ** state)68 static int setup_both_keys_passphrase(void **state)
69 {
70     ssh_session session;
71 
72     torture_write_file(LIBSSH_RSA_TESTKEY,
73                        torture_get_testkey(SSH_KEYTYPE_RSA, 1));
74     torture_write_file(LIBSSH_RSA_TESTKEY ".pub",
75                        torture_get_testkey_pub(SSH_KEYTYPE_RSA));
76 
77 #ifdef HAVE_DSA
78     torture_write_file(LIBSSH_DSA_TESTKEY,
79                        torture_get_testkey(SSH_KEYTYPE_DSS, 1));
80     torture_write_file(LIBSSH_DSA_TESTKEY ".pub",
81                        torture_get_testkey_pub(SSH_KEYTYPE_DSS));
82 #endif
83 
84     session = ssh_new();
85     *state = session;
86 
87     return 0;
88 }
89 
teardown(void ** state)90 static int teardown(void **state)
91 {
92 #ifdef HAVE_DSA
93     unlink(LIBSSH_DSA_TESTKEY);
94     unlink(LIBSSH_DSA_TESTKEY ".pub");
95 #endif
96 
97     unlink(LIBSSH_RSA_TESTKEY);
98     unlink(LIBSSH_RSA_TESTKEY ".pub");
99 
100     ssh_free(*state);
101 
102     return 0;
103 }
104 
torture_pubkey_from_file(void ** state)105 static void torture_pubkey_from_file(void **state) {
106     ssh_session session = *state;
107     ssh_string pubkey = NULL;
108     int type, rc;
109 
110     rc = ssh_try_publickey_from_file(session, LIBSSH_RSA_TESTKEY, &pubkey, &type);
111 
112     assert_true(rc == 0);
113 
114     SSH_STRING_FREE(pubkey);
115 
116     /* test if it returns 1 if pubkey doesn't exist */
117     unlink(LIBSSH_RSA_TESTKEY ".pub");
118 
119     rc = ssh_try_publickey_from_file(session, LIBSSH_RSA_TESTKEY, &pubkey, &type);
120     assert_true(rc == 1);
121 
122     /* This free is unnecessary, but the static analyser does not know */
123     SSH_STRING_FREE(pubkey);
124 
125     /* test if it returns -1 if privkey doesn't exist */
126     unlink(LIBSSH_RSA_TESTKEY);
127 
128     rc = ssh_try_publickey_from_file(session, LIBSSH_RSA_TESTKEY, &pubkey, &type);
129     assert_true(rc == -1);
130 
131     /* This free is unnecessary, but the static analyser does not know */
132     SSH_STRING_FREE(pubkey);
133 }
134 
torture_read_one_line(const char * filename,char * buffer,size_t len)135 static int torture_read_one_line(const char *filename, char *buffer, size_t len)
136 {
137     FILE *fp;
138     size_t nmemb;
139 
140     fp = fopen(filename, "r");
141     if (fp == NULL) {
142         return -1;
143     }
144 
145     nmemb = fread(buffer, len - 2, 1, fp);
146     if (nmemb != 0 || ferror(fp)) {
147         fclose(fp);
148         return -1;
149     }
150     buffer[len - 1] = '\0';
151 
152     fclose(fp);
153 
154     return 0;
155 }
156 
torture_pubkey_generate_from_privkey(void ** state)157 static void torture_pubkey_generate_from_privkey(void **state) {
158     ssh_session session = *state;
159     ssh_private_key privkey = NULL;
160     ssh_public_key pubkey = NULL;
161     ssh_string pubkey_orig = NULL;
162     ssh_string pubkey_new = NULL;
163     char pubkey_line_orig[512] = {0};
164     char pubkey_line_new[512] = {0};
165     char *p;
166     int type_orig = 0;
167     int type_new = 0;
168     int rc;
169 
170     /* read the publickey */
171     rc = ssh_try_publickey_from_file(session, LIBSSH_RSA_TESTKEY, &pubkey_orig,
172         &type_orig);
173     assert_true(rc == 0);
174     assert_non_null(pubkey_orig);
175 
176     rc = torture_read_one_line(LIBSSH_RSA_TESTKEY ".pub", pubkey_line_orig,
177         sizeof(pubkey_line_orig));
178     assert_true(rc == 0);
179 
180     /* remove the public key, generate it from the private key and write it. */
181     unlink(LIBSSH_RSA_TESTKEY ".pub");
182 
183     privkey = privatekey_from_file(session, LIBSSH_RSA_TESTKEY, 0, NULL);
184     assert_non_null(privkey);
185 
186     pubkey = publickey_from_privatekey(privkey);
187     assert_non_null(pubkey);
188     type_new = privkey->type;
189     privatekey_free(privkey);
190 
191     pubkey_new = publickey_to_string(pubkey);
192     publickey_free(pubkey);
193 
194     assert_non_null(pubkey_new);
195 
196     assert_true(ssh_string_len(pubkey_orig) == ssh_string_len(pubkey_new));
197     assert_memory_equal(ssh_string_data(pubkey_orig),
198                         ssh_string_data(pubkey_new),
199                         ssh_string_len(pubkey_orig));
200 
201     rc = ssh_publickey_to_file(session, LIBSSH_RSA_TESTKEY ".pub", pubkey_new, type_new);
202     assert_true(rc == 0);
203 
204     rc = torture_read_one_line(LIBSSH_RSA_TESTKEY ".pub", pubkey_line_new,
205         sizeof(pubkey_line_new));
206     assert_true(rc == 0);
207 
208     /* do not compare hostname */
209     p = strrchr(pubkey_line_orig, ' ');
210     if (p != NULL) {
211         *p = '\0';
212     }
213     p = strrchr(pubkey_line_new, ' ');
214     if (p != NULL) {
215         *p = '\0';
216     }
217 
218     assert_string_equal(pubkey_line_orig, pubkey_line_new);
219 
220     SSH_STRING_FREE(pubkey_orig);
221     SSH_STRING_FREE(pubkey_new);
222 }
223 
224 /**
225  * @brief tests the privatekey_from_file function without passphrase
226  */
torture_privatekey_from_file(void ** state)227 static void torture_privatekey_from_file(void **state) {
228     ssh_session session = *state;
229     ssh_private_key key = NULL;
230 
231     key = privatekey_from_file(session, LIBSSH_RSA_TESTKEY, SSH_KEYTYPE_RSA, NULL);
232     assert_non_null(key);
233     if (key != NULL) {
234         privatekey_free(key);
235         key = NULL;
236     }
237 
238 #ifdef HAVE_DSA
239     key = privatekey_from_file(session, LIBSSH_DSA_TESTKEY, SSH_KEYTYPE_DSS, NULL);
240     assert_non_null(key);
241     if (key != NULL) {
242         privatekey_free(key);
243         key = NULL;
244     }
245 #endif
246 
247     /* Test the automatic type discovery */
248     key = privatekey_from_file(session, LIBSSH_RSA_TESTKEY, 0, NULL);
249     assert_non_null(key);
250     if (key != NULL) {
251         privatekey_free(key);
252         key = NULL;
253     }
254 
255 #ifdef HAVE_DSA
256     key = privatekey_from_file(session, LIBSSH_DSA_TESTKEY, 0, NULL);
257     assert_non_null(key);
258     if (key != NULL) {
259         privatekey_free(key);
260         key = NULL;
261     }
262 #endif
263 }
264 
265 /**
266  * @brief tests the privatekey_from_file function with passphrase
267  */
torture_privatekey_from_file_passphrase(void ** state)268 static void torture_privatekey_from_file_passphrase(void **state) {
269     ssh_session session = *state;
270     ssh_private_key key = NULL;
271 
272     key = privatekey_from_file(session, LIBSSH_RSA_TESTKEY, SSH_KEYTYPE_RSA, TORTURE_TESTKEY_PASSWORD);
273     assert_non_null(key);
274     if (key != NULL) {
275         privatekey_free(key);
276         key = NULL;
277     }
278 
279 #ifdef HAVE_DSA
280     key = privatekey_from_file(session, LIBSSH_DSA_TESTKEY, SSH_KEYTYPE_DSS, TORTURE_TESTKEY_PASSWORD);
281     assert_non_null(key);
282     if (key != NULL) {
283         privatekey_free(key);
284         key = NULL;
285     }
286 #endif
287 
288     /* Test the automatic type discovery */
289     key = privatekey_from_file(session, LIBSSH_RSA_TESTKEY, 0, TORTURE_TESTKEY_PASSWORD);
290     assert_non_null(key);
291     if (key != NULL) {
292         privatekey_free(key);
293         key = NULL;
294     }
295 
296 #ifdef HAVE_DSA
297     key = privatekey_from_file(session, LIBSSH_DSA_TESTKEY, 0, TORTURE_TESTKEY_PASSWORD);
298     assert_non_null(key);
299     if (key != NULL) {
300         privatekey_free(key);
301         key = NULL;
302     }
303 #endif
304 }
305 
torture_run_tests(void)306 int torture_run_tests(void) {
307     int rc;
308     struct CMUnitTest tests[] = {
309         cmocka_unit_test_setup_teardown(torture_pubkey_from_file,
310                                         setup_rsa_key,
311                                         teardown),
312         cmocka_unit_test_setup_teardown(torture_pubkey_generate_from_privkey,
313                                         setup_rsa_key,
314                                         teardown),
315         cmocka_unit_test_setup_teardown(torture_privatekey_from_file,
316                                         setup_both_keys,
317                                         teardown),
318         cmocka_unit_test_setup_teardown(torture_privatekey_from_file_passphrase,
319                                         setup_both_keys_passphrase,
320                                         teardown),
321     };
322 
323 
324     ssh_init();
325     torture_filter_tests(tests);
326     rc = cmocka_run_group_tests(tests, NULL, NULL);
327     ssh_finalize();
328     return rc;
329 }
330