diff options
Diffstat (limited to 'regress/unittests/sshkey/test_sshkey.c')
-rw-r--r-- | regress/unittests/sshkey/test_sshkey.c | 357 |
1 files changed, 357 insertions, 0 deletions
diff --git a/regress/unittests/sshkey/test_sshkey.c b/regress/unittests/sshkey/test_sshkey.c new file mode 100644 index 000000000..ef0c67956 --- /dev/null +++ b/regress/unittests/sshkey/test_sshkey.c | |||
@@ -0,0 +1,357 @@ | |||
1 | /* $OpenBSD: test_sshkey.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */ | ||
2 | /* | ||
3 | * Regress test for sshkey.h key management API | ||
4 | * | ||
5 | * Placed in the public domain | ||
6 | */ | ||
7 | |||
8 | #include "includes.h" | ||
9 | |||
10 | #include <sys/types.h> | ||
11 | #include <sys/param.h> | ||
12 | #include <stdio.h> | ||
13 | #ifdef HAVE_STDINT_H | ||
14 | #include <stdint.h> | ||
15 | #endif | ||
16 | #include <stdlib.h> | ||
17 | #include <string.h> | ||
18 | |||
19 | #include <openssl/bn.h> | ||
20 | #include <openssl/rsa.h> | ||
21 | #include <openssl/dsa.h> | ||
22 | #ifdef OPENSSL_HAS_NISTP256 | ||
23 | # include <openssl/ec.h> | ||
24 | #endif | ||
25 | |||
26 | #include "../test_helper/test_helper.h" | ||
27 | |||
28 | #include "ssherr.h" | ||
29 | #include "sshbuf.h" | ||
30 | #define SSHBUF_INTERNAL 1 /* access internals for testing */ | ||
31 | #include "sshkey.h" | ||
32 | |||
33 | #include "authfile.h" | ||
34 | #include "common.h" | ||
35 | #include "ssh2.h" | ||
36 | |||
37 | void sshkey_tests(void); | ||
38 | |||
39 | static void | ||
40 | build_cert(struct sshbuf *b, const struct sshkey *k, const char *type, | ||
41 | const struct sshkey *sign_key, const struct sshkey *ca_key) | ||
42 | { | ||
43 | struct sshbuf *ca_buf, *pk, *principals, *critopts, *exts; | ||
44 | u_char *sigblob; | ||
45 | size_t siglen; | ||
46 | |||
47 | ca_buf = sshbuf_new(); | ||
48 | ASSERT_INT_EQ(sshkey_to_blob_buf(ca_key, ca_buf), 0); | ||
49 | |||
50 | /* | ||
51 | * Get the public key serialisation by rendering the key and skipping | ||
52 | * the type string. This is a bit of a hack :/ | ||
53 | */ | ||
54 | pk = sshbuf_new(); | ||
55 | ASSERT_INT_EQ(sshkey_plain_to_blob_buf(k, pk), 0); | ||
56 | ASSERT_INT_EQ(sshbuf_skip_string(pk), 0); | ||
57 | |||
58 | principals = sshbuf_new(); | ||
59 | ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0); | ||
60 | ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0); | ||
61 | |||
62 | critopts = sshbuf_new(); | ||
63 | /* XXX fill this in */ | ||
64 | |||
65 | exts = sshbuf_new(); | ||
66 | /* XXX fill this in */ | ||
67 | |||
68 | ASSERT_INT_EQ(sshbuf_put_cstring(b, type), 0); | ||
69 | ASSERT_INT_EQ(sshbuf_put_cstring(b, "noncenoncenonce!"), 0); /* nonce */ | ||
70 | ASSERT_INT_EQ(sshbuf_putb(b, pk), 0); /* public key serialisation */ | ||
71 | ASSERT_INT_EQ(sshbuf_put_u64(b, 1234), 0); /* serial */ | ||
72 | ASSERT_INT_EQ(sshbuf_put_u32(b, SSH2_CERT_TYPE_USER), 0); /* type */ | ||
73 | ASSERT_INT_EQ(sshbuf_put_cstring(b, "gregor"), 0); /* key ID */ | ||
74 | ASSERT_INT_EQ(sshbuf_put_stringb(b, principals), 0); /* principals */ | ||
75 | ASSERT_INT_EQ(sshbuf_put_u64(b, 0), 0); /* start */ | ||
76 | ASSERT_INT_EQ(sshbuf_put_u64(b, 0xffffffffffffffffULL), 0); /* end */ | ||
77 | ASSERT_INT_EQ(sshbuf_put_stringb(b, critopts), 0); /* options */ | ||
78 | ASSERT_INT_EQ(sshbuf_put_stringb(b, exts), 0); /* extensions */ | ||
79 | ASSERT_INT_EQ(sshbuf_put_string(b, NULL, 0), 0); /* reserved */ | ||
80 | ASSERT_INT_EQ(sshbuf_put_stringb(b, ca_buf), 0); /* signature key */ | ||
81 | ASSERT_INT_EQ(sshkey_sign(sign_key, &sigblob, &siglen, | ||
82 | sshbuf_ptr(b), sshbuf_len(b), 0), 0); | ||
83 | ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */ | ||
84 | |||
85 | free(sigblob); | ||
86 | sshbuf_free(ca_buf); | ||
87 | sshbuf_free(exts); | ||
88 | sshbuf_free(critopts); | ||
89 | sshbuf_free(principals); | ||
90 | sshbuf_free(pk); | ||
91 | } | ||
92 | |||
93 | void | ||
94 | sshkey_tests(void) | ||
95 | { | ||
96 | struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *ke, *kf; | ||
97 | struct sshbuf *b; | ||
98 | |||
99 | TEST_START("new invalid"); | ||
100 | k1 = sshkey_new(-42); | ||
101 | ASSERT_PTR_EQ(k1, NULL); | ||
102 | TEST_DONE(); | ||
103 | |||
104 | TEST_START("new/free KEY_UNSPEC"); | ||
105 | k1 = sshkey_new(KEY_UNSPEC); | ||
106 | ASSERT_PTR_NE(k1, NULL); | ||
107 | sshkey_free(k1); | ||
108 | TEST_DONE(); | ||
109 | |||
110 | TEST_START("new/free KEY_RSA1"); | ||
111 | k1 = sshkey_new(KEY_RSA1); | ||
112 | ASSERT_PTR_NE(k1, NULL); | ||
113 | ASSERT_PTR_NE(k1->rsa, NULL); | ||
114 | ASSERT_PTR_NE(k1->rsa->n, NULL); | ||
115 | ASSERT_PTR_NE(k1->rsa->e, NULL); | ||
116 | ASSERT_PTR_EQ(k1->rsa->p, NULL); | ||
117 | sshkey_free(k1); | ||
118 | TEST_DONE(); | ||
119 | |||
120 | TEST_START("new/free KEY_RSA"); | ||
121 | k1 = sshkey_new(KEY_RSA); | ||
122 | ASSERT_PTR_NE(k1, NULL); | ||
123 | ASSERT_PTR_NE(k1->rsa, NULL); | ||
124 | ASSERT_PTR_NE(k1->rsa->n, NULL); | ||
125 | ASSERT_PTR_NE(k1->rsa->e, NULL); | ||
126 | ASSERT_PTR_EQ(k1->rsa->p, NULL); | ||
127 | sshkey_free(k1); | ||
128 | TEST_DONE(); | ||
129 | |||
130 | TEST_START("new/free KEY_DSA"); | ||
131 | k1 = sshkey_new(KEY_DSA); | ||
132 | ASSERT_PTR_NE(k1, NULL); | ||
133 | ASSERT_PTR_NE(k1->dsa, NULL); | ||
134 | ASSERT_PTR_NE(k1->dsa->g, NULL); | ||
135 | ASSERT_PTR_EQ(k1->dsa->priv_key, NULL); | ||
136 | sshkey_free(k1); | ||
137 | TEST_DONE(); | ||
138 | |||
139 | TEST_START("new/free KEY_ECDSA"); | ||
140 | k1 = sshkey_new(KEY_ECDSA); | ||
141 | ASSERT_PTR_NE(k1, NULL); | ||
142 | ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */ | ||
143 | sshkey_free(k1); | ||
144 | TEST_DONE(); | ||
145 | |||
146 | TEST_START("new/free KEY_ED25519"); | ||
147 | k1 = sshkey_new(KEY_ED25519); | ||
148 | ASSERT_PTR_NE(k1, NULL); | ||
149 | /* These should be blank until key loaded or generated */ | ||
150 | ASSERT_PTR_EQ(k1->ed25519_sk, NULL); | ||
151 | ASSERT_PTR_EQ(k1->ed25519_pk, NULL); | ||
152 | sshkey_free(k1); | ||
153 | TEST_DONE(); | ||
154 | |||
155 | TEST_START("new_private KEY_RSA"); | ||
156 | k1 = sshkey_new_private(KEY_RSA); | ||
157 | ASSERT_PTR_NE(k1, NULL); | ||
158 | ASSERT_PTR_NE(k1->rsa, NULL); | ||
159 | ASSERT_PTR_NE(k1->rsa->n, NULL); | ||
160 | ASSERT_PTR_NE(k1->rsa->e, NULL); | ||
161 | ASSERT_PTR_NE(k1->rsa->p, NULL); | ||
162 | ASSERT_INT_EQ(sshkey_add_private(k1), 0); | ||
163 | sshkey_free(k1); | ||
164 | TEST_DONE(); | ||
165 | |||
166 | TEST_START("new_private KEY_DSA"); | ||
167 | k1 = sshkey_new_private(KEY_DSA); | ||
168 | ASSERT_PTR_NE(k1, NULL); | ||
169 | ASSERT_PTR_NE(k1->dsa, NULL); | ||
170 | ASSERT_PTR_NE(k1->dsa->g, NULL); | ||
171 | ASSERT_PTR_NE(k1->dsa->priv_key, NULL); | ||
172 | ASSERT_INT_EQ(sshkey_add_private(k1), 0); | ||
173 | sshkey_free(k1); | ||
174 | TEST_DONE(); | ||
175 | |||
176 | TEST_START("generate KEY_RSA too small modulus"); | ||
177 | ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 128, &k1), | ||
178 | SSH_ERR_INVALID_ARGUMENT); | ||
179 | ASSERT_PTR_EQ(k1, NULL); | ||
180 | TEST_DONE(); | ||
181 | |||
182 | TEST_START("generate KEY_RSA too large modulus"); | ||
183 | ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1 << 20, &k1), | ||
184 | SSH_ERR_INVALID_ARGUMENT); | ||
185 | ASSERT_PTR_EQ(k1, NULL); | ||
186 | TEST_DONE(); | ||
187 | |||
188 | TEST_START("generate KEY_DSA wrong bits"); | ||
189 | ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 2048, &k1), | ||
190 | SSH_ERR_INVALID_ARGUMENT); | ||
191 | ASSERT_PTR_EQ(k1, NULL); | ||
192 | sshkey_free(k1); | ||
193 | TEST_DONE(); | ||
194 | |||
195 | TEST_START("generate KEY_ECDSA wrong bits"); | ||
196 | ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1), | ||
197 | SSH_ERR_INVALID_ARGUMENT); | ||
198 | ASSERT_PTR_EQ(k1, NULL); | ||
199 | sshkey_free(k1); | ||
200 | TEST_DONE(); | ||
201 | |||
202 | TEST_START("generate KEY_RSA"); | ||
203 | ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 768, &kr), 0); | ||
204 | ASSERT_PTR_NE(kr, NULL); | ||
205 | ASSERT_PTR_NE(kr->rsa, NULL); | ||
206 | ASSERT_PTR_NE(kr->rsa->n, NULL); | ||
207 | ASSERT_PTR_NE(kr->rsa->e, NULL); | ||
208 | ASSERT_PTR_NE(kr->rsa->p, NULL); | ||
209 | ASSERT_INT_EQ(BN_num_bits(kr->rsa->n), 768); | ||
210 | TEST_DONE(); | ||
211 | |||
212 | TEST_START("generate KEY_DSA"); | ||
213 | ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0); | ||
214 | ASSERT_PTR_NE(kd, NULL); | ||
215 | ASSERT_PTR_NE(kd->dsa, NULL); | ||
216 | ASSERT_PTR_NE(kd->dsa->g, NULL); | ||
217 | ASSERT_PTR_NE(kd->dsa->priv_key, NULL); | ||
218 | TEST_DONE(); | ||
219 | |||
220 | #ifdef OPENSSL_HAS_ECC | ||
221 | TEST_START("generate KEY_ECDSA"); | ||
222 | ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &ke), 0); | ||
223 | ASSERT_PTR_NE(ke, NULL); | ||
224 | ASSERT_PTR_NE(ke->ecdsa, NULL); | ||
225 | ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL); | ||
226 | ASSERT_PTR_NE(EC_KEY_get0_private_key(ke->ecdsa), NULL); | ||
227 | TEST_DONE(); | ||
228 | #endif | ||
229 | |||
230 | TEST_START("generate KEY_ED25519"); | ||
231 | ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &kf), 0); | ||
232 | ASSERT_PTR_NE(kf, NULL); | ||
233 | ASSERT_INT_EQ(kf->type, KEY_ED25519); | ||
234 | ASSERT_PTR_NE(kf->ed25519_pk, NULL); | ||
235 | ASSERT_PTR_NE(kf->ed25519_sk, NULL); | ||
236 | TEST_DONE(); | ||
237 | |||
238 | TEST_START("demote KEY_RSA"); | ||
239 | ASSERT_INT_EQ(sshkey_demote(kr, &k1), 0); | ||
240 | ASSERT_PTR_NE(k1, NULL); | ||
241 | ASSERT_PTR_NE(kr, k1); | ||
242 | ASSERT_INT_EQ(k1->type, KEY_RSA); | ||
243 | ASSERT_PTR_NE(k1->rsa, NULL); | ||
244 | ASSERT_PTR_NE(k1->rsa->n, NULL); | ||
245 | ASSERT_PTR_NE(k1->rsa->e, NULL); | ||
246 | ASSERT_PTR_EQ(k1->rsa->p, NULL); | ||
247 | TEST_DONE(); | ||
248 | |||
249 | TEST_START("equal KEY_RSA/demoted KEY_RSA"); | ||
250 | ASSERT_INT_EQ(sshkey_equal(kr, k1), 1); | ||
251 | sshkey_free(k1); | ||
252 | TEST_DONE(); | ||
253 | |||
254 | TEST_START("demote KEY_DSA"); | ||
255 | ASSERT_INT_EQ(sshkey_demote(kd, &k1), 0); | ||
256 | ASSERT_PTR_NE(k1, NULL); | ||
257 | ASSERT_PTR_NE(kd, k1); | ||
258 | ASSERT_INT_EQ(k1->type, KEY_DSA); | ||
259 | ASSERT_PTR_NE(k1->dsa, NULL); | ||
260 | ASSERT_PTR_NE(k1->dsa->g, NULL); | ||
261 | ASSERT_PTR_EQ(k1->dsa->priv_key, NULL); | ||
262 | TEST_DONE(); | ||
263 | |||
264 | TEST_START("equal KEY_DSA/demoted KEY_DSA"); | ||
265 | ASSERT_INT_EQ(sshkey_equal(kd, k1), 1); | ||
266 | sshkey_free(k1); | ||
267 | TEST_DONE(); | ||
268 | |||
269 | #ifdef OPENSSL_HAS_ECC | ||
270 | TEST_START("demote KEY_ECDSA"); | ||
271 | ASSERT_INT_EQ(sshkey_demote(ke, &k1), 0); | ||
272 | ASSERT_PTR_NE(k1, NULL); | ||
273 | ASSERT_PTR_NE(ke, k1); | ||
274 | ASSERT_INT_EQ(k1->type, KEY_ECDSA); | ||
275 | ASSERT_PTR_NE(k1->ecdsa, NULL); | ||
276 | ASSERT_INT_EQ(k1->ecdsa_nid, ke->ecdsa_nid); | ||
277 | ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL); | ||
278 | ASSERT_PTR_EQ(EC_KEY_get0_private_key(k1->ecdsa), NULL); | ||
279 | TEST_DONE(); | ||
280 | |||
281 | TEST_START("equal KEY_ECDSA/demoted KEY_ECDSA"); | ||
282 | ASSERT_INT_EQ(sshkey_equal(ke, k1), 1); | ||
283 | sshkey_free(k1); | ||
284 | TEST_DONE(); | ||
285 | #endif | ||
286 | |||
287 | TEST_START("demote KEY_ED25519"); | ||
288 | ASSERT_INT_EQ(sshkey_demote(kf, &k1), 0); | ||
289 | ASSERT_PTR_NE(k1, NULL); | ||
290 | ASSERT_PTR_NE(kf, k1); | ||
291 | ASSERT_INT_EQ(k1->type, KEY_ED25519); | ||
292 | ASSERT_PTR_NE(k1->ed25519_pk, NULL); | ||
293 | ASSERT_PTR_EQ(k1->ed25519_sk, NULL); | ||
294 | TEST_DONE(); | ||
295 | |||
296 | TEST_START("equal KEY_ED25519/demoted KEY_ED25519"); | ||
297 | ASSERT_INT_EQ(sshkey_equal(kf, k1), 1); | ||
298 | sshkey_free(k1); | ||
299 | TEST_DONE(); | ||
300 | |||
301 | TEST_START("equal mismatched key types"); | ||
302 | ASSERT_INT_EQ(sshkey_equal(kd, kr), 0); | ||
303 | #ifdef OPENSSL_HAS_ECC | ||
304 | ASSERT_INT_EQ(sshkey_equal(kd, ke), 0); | ||
305 | ASSERT_INT_EQ(sshkey_equal(kr, ke), 0); | ||
306 | ASSERT_INT_EQ(sshkey_equal(ke, kf), 0); | ||
307 | #endif | ||
308 | ASSERT_INT_EQ(sshkey_equal(kd, kf), 0); | ||
309 | TEST_DONE(); | ||
310 | |||
311 | TEST_START("equal different keys"); | ||
312 | ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 768, &k1), 0); | ||
313 | ASSERT_INT_EQ(sshkey_equal(kr, k1), 0); | ||
314 | sshkey_free(k1); | ||
315 | ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &k1), 0); | ||
316 | ASSERT_INT_EQ(sshkey_equal(kd, k1), 0); | ||
317 | sshkey_free(k1); | ||
318 | #ifdef OPENSSL_HAS_ECC | ||
319 | ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &k1), 0); | ||
320 | ASSERT_INT_EQ(sshkey_equal(ke, k1), 0); | ||
321 | sshkey_free(k1); | ||
322 | #endif | ||
323 | ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &k1), 0); | ||
324 | ASSERT_INT_EQ(sshkey_equal(kf, k1), 0); | ||
325 | sshkey_free(k1); | ||
326 | TEST_DONE(); | ||
327 | |||
328 | sshkey_free(kr); | ||
329 | sshkey_free(kd); | ||
330 | #ifdef OPENSSL_HAS_ECC | ||
331 | sshkey_free(ke); | ||
332 | #endif | ||
333 | sshkey_free(kf); | ||
334 | |||
335 | /* XXX certify test */ | ||
336 | /* XXX sign test */ | ||
337 | /* XXX verify test */ | ||
338 | |||
339 | TEST_START("nested certificate"); | ||
340 | ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0); | ||
341 | ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, | ||
342 | NULL), 0); | ||
343 | b = load_file("rsa_2"); | ||
344 | ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", "rsa_1", | ||
345 | &k3, NULL), 0); | ||
346 | sshbuf_reset(b); | ||
347 | build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1); | ||
348 | ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4), | ||
349 | SSH_ERR_KEY_CERT_INVALID_SIGN_KEY); | ||
350 | ASSERT_PTR_EQ(k4, NULL); | ||
351 | sshbuf_free(b); | ||
352 | sshkey_free(k1); | ||
353 | sshkey_free(k2); | ||
354 | sshkey_free(k3); | ||
355 | TEST_DONE(); | ||
356 | |||
357 | } | ||