1323124Sdes/* 	$OpenBSD: test_sshkey.c,v 1.10 2016/05/02 09:52:00 djm Exp $ */
2276707Sdes/*
3276707Sdes * Regress test for sshkey.h key management API
4276707Sdes *
5276707Sdes * Placed in the public domain
6276707Sdes */
7276707Sdes
8276707Sdes#include "includes.h"
9276707Sdes
10276707Sdes#include <sys/types.h>
11276707Sdes#include <sys/param.h>
12276707Sdes#include <stdio.h>
13276707Sdes#ifdef HAVE_STDINT_H
14276707Sdes#include <stdint.h>
15276707Sdes#endif
16276707Sdes#include <stdlib.h>
17276707Sdes#include <string.h>
18276707Sdes
19276707Sdes#include <openssl/bn.h>
20276707Sdes#include <openssl/rsa.h>
21276707Sdes#include <openssl/dsa.h>
22295367Sdes#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256)
23276707Sdes# include <openssl/ec.h>
24276707Sdes#endif
25276707Sdes
26276707Sdes#include "../test_helper/test_helper.h"
27276707Sdes
28276707Sdes#include "ssherr.h"
29276707Sdes#include "sshbuf.h"
30276707Sdes#define SSHBUF_INTERNAL 1	/* access internals for testing */
31276707Sdes#include "sshkey.h"
32276707Sdes
33276707Sdes#include "authfile.h"
34276707Sdes#include "common.h"
35276707Sdes#include "ssh2.h"
36276707Sdes
37276707Sdesvoid sshkey_tests(void);
38276707Sdes
39276707Sdesstatic void
40295367Sdesput_opt(struct sshbuf *b, const char *name, const char *value)
41295367Sdes{
42295367Sdes	struct sshbuf *sect;
43295367Sdes
44295367Sdes	sect = sshbuf_new();
45295367Sdes	ASSERT_PTR_NE(sect, NULL);
46295367Sdes	ASSERT_INT_EQ(sshbuf_put_cstring(b, name), 0);
47295367Sdes	if (value != NULL)
48295367Sdes		ASSERT_INT_EQ(sshbuf_put_cstring(sect, value), 0);
49295367Sdes	ASSERT_INT_EQ(sshbuf_put_stringb(b, sect), 0);
50295367Sdes	sshbuf_free(sect);
51295367Sdes}
52295367Sdes
53295367Sdesstatic void
54276707Sdesbuild_cert(struct sshbuf *b, const struct sshkey *k, const char *type,
55296781Sdes    const struct sshkey *sign_key, const struct sshkey *ca_key,
56296781Sdes    const char *sig_alg)
57276707Sdes{
58276707Sdes	struct sshbuf *ca_buf, *pk, *principals, *critopts, *exts;
59276707Sdes	u_char *sigblob;
60276707Sdes	size_t siglen;
61276707Sdes
62276707Sdes	ca_buf = sshbuf_new();
63295367Sdes	ASSERT_PTR_NE(ca_buf, NULL);
64295367Sdes	ASSERT_INT_EQ(sshkey_putb(ca_key, ca_buf), 0);
65276707Sdes
66276707Sdes	/*
67276707Sdes	 * Get the public key serialisation by rendering the key and skipping
68276707Sdes	 * the type string. This is a bit of a hack :/
69276707Sdes	 */
70276707Sdes	pk = sshbuf_new();
71295367Sdes	ASSERT_PTR_NE(pk, NULL);
72295367Sdes	ASSERT_INT_EQ(sshkey_putb_plain(k, pk), 0);
73276707Sdes	ASSERT_INT_EQ(sshbuf_skip_string(pk), 0);
74276707Sdes
75276707Sdes	principals = sshbuf_new();
76295367Sdes	ASSERT_PTR_NE(principals, NULL);
77276707Sdes	ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0);
78276707Sdes	ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0);
79276707Sdes
80276707Sdes	critopts = sshbuf_new();
81295367Sdes	ASSERT_PTR_NE(critopts, NULL);
82295367Sdes	put_opt(critopts, "force-command", "/usr/local/bin/nethack");
83295367Sdes	put_opt(critopts, "source-address", "192.168.0.0/24,127.0.0.1,::1");
84276707Sdes
85276707Sdes	exts = sshbuf_new();
86295367Sdes	ASSERT_PTR_NE(exts, NULL);
87295367Sdes	put_opt(critopts, "permit-X11-forwarding", NULL);
88276707Sdes
89276707Sdes	ASSERT_INT_EQ(sshbuf_put_cstring(b, type), 0);
90276707Sdes	ASSERT_INT_EQ(sshbuf_put_cstring(b, "noncenoncenonce!"), 0); /* nonce */
91276707Sdes	ASSERT_INT_EQ(sshbuf_putb(b, pk), 0); /* public key serialisation */
92276707Sdes	ASSERT_INT_EQ(sshbuf_put_u64(b, 1234), 0); /* serial */
93276707Sdes	ASSERT_INT_EQ(sshbuf_put_u32(b, SSH2_CERT_TYPE_USER), 0); /* type */
94276707Sdes	ASSERT_INT_EQ(sshbuf_put_cstring(b, "gregor"), 0); /* key ID */
95276707Sdes	ASSERT_INT_EQ(sshbuf_put_stringb(b, principals), 0); /* principals */
96276707Sdes	ASSERT_INT_EQ(sshbuf_put_u64(b, 0), 0); /* start */
97276707Sdes	ASSERT_INT_EQ(sshbuf_put_u64(b, 0xffffffffffffffffULL), 0); /* end */
98276707Sdes	ASSERT_INT_EQ(sshbuf_put_stringb(b, critopts), 0); /* options */
99276707Sdes	ASSERT_INT_EQ(sshbuf_put_stringb(b, exts), 0); /* extensions */
100276707Sdes	ASSERT_INT_EQ(sshbuf_put_string(b, NULL, 0), 0); /* reserved */
101276707Sdes	ASSERT_INT_EQ(sshbuf_put_stringb(b, ca_buf), 0); /* signature key */
102276707Sdes	ASSERT_INT_EQ(sshkey_sign(sign_key, &sigblob, &siglen,
103296781Sdes	    sshbuf_ptr(b), sshbuf_len(b), sig_alg, 0), 0);
104276707Sdes	ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */
105276707Sdes
106276707Sdes	free(sigblob);
107276707Sdes	sshbuf_free(ca_buf);
108276707Sdes	sshbuf_free(exts);
109276707Sdes	sshbuf_free(critopts);
110276707Sdes	sshbuf_free(principals);
111276707Sdes	sshbuf_free(pk);
112276707Sdes}
113276707Sdes
114295367Sdesstatic void
115296781Sdessignature_test(struct sshkey *k, struct sshkey *bad, const char *sig_alg,
116296781Sdes    const u_char *d, size_t l)
117295367Sdes{
118295367Sdes	size_t len;
119295367Sdes	u_char *sig;
120295367Sdes
121296781Sdes	ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, sig_alg, 0), 0);
122295367Sdes	ASSERT_SIZE_T_GT(len, 8);
123295367Sdes	ASSERT_PTR_NE(sig, NULL);
124295367Sdes	ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, 0), 0);
125295367Sdes	ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, 0), 0);
126295367Sdes	/* Fuzz test is more comprehensive, this is just a smoke test */
127295367Sdes	sig[len - 5] ^= 0x10;
128295367Sdes	ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, 0), 0);
129295367Sdes	free(sig);
130295367Sdes}
131295367Sdes
132295367Sdesstatic void
133295367Sdesbanana(u_char *s, size_t l)
134295367Sdes{
135295367Sdes	size_t o;
136295367Sdes	const u_char the_banana[] = { 'b', 'a', 'n', 'a', 'n', 'a' };
137295367Sdes
138295367Sdes	for (o = 0; o < l; o += sizeof(the_banana)) {
139295367Sdes		if (l - o < sizeof(the_banana)) {
140295367Sdes			memcpy(s + o, "nanananana", l - o);
141295367Sdes			break;
142295367Sdes		}
143295367Sdes		memcpy(s + o, banana, sizeof(the_banana));
144295367Sdes	}
145295367Sdes}
146295367Sdes
147295367Sdesstatic void
148296781Sdessignature_tests(struct sshkey *k, struct sshkey *bad, const char *sig_alg)
149295367Sdes{
150295367Sdes	u_char i, buf[2049];
151295367Sdes	size_t lens[] = {
152295367Sdes		1, 2, 7, 8, 9, 15, 16, 17, 31, 32, 33, 127, 128, 129,
153295367Sdes		255, 256, 257, 1023, 1024, 1025, 2047, 2048, 2049
154295367Sdes	};
155295367Sdes
156295367Sdes	for (i = 0; i < (sizeof(lens)/sizeof(lens[0])); i++) {
157295367Sdes		test_subtest_info("%s key, banana length %zu",
158295367Sdes		    sshkey_type(k), lens[i]);
159295367Sdes		banana(buf, lens[i]);
160296781Sdes		signature_test(k, bad, sig_alg, buf, lens[i]);
161295367Sdes	}
162295367Sdes}
163295367Sdes
164295367Sdesstatic struct sshkey *
165295367Sdesget_private(const char *n)
166295367Sdes{
167295367Sdes	struct sshbuf *b;
168295367Sdes	struct sshkey *ret;
169295367Sdes
170295367Sdes	b = load_file(n);
171296781Sdes	ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", &ret, NULL), 0);
172295367Sdes	sshbuf_free(b);
173295367Sdes	return ret;
174295367Sdes}
175295367Sdes
176276707Sdesvoid
177276707Sdessshkey_tests(void)
178276707Sdes{
179295367Sdes	struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *kf;
180295367Sdes#ifdef OPENSSL_HAS_ECC
181295367Sdes	struct sshkey *ke;
182295367Sdes#endif
183276707Sdes	struct sshbuf *b;
184276707Sdes
185276707Sdes	TEST_START("new invalid");
186276707Sdes	k1 = sshkey_new(-42);
187276707Sdes	ASSERT_PTR_EQ(k1, NULL);
188276707Sdes	TEST_DONE();
189276707Sdes
190276707Sdes	TEST_START("new/free KEY_UNSPEC");
191276707Sdes	k1 = sshkey_new(KEY_UNSPEC);
192276707Sdes	ASSERT_PTR_NE(k1, NULL);
193276707Sdes	sshkey_free(k1);
194276707Sdes	TEST_DONE();
195276707Sdes
196276707Sdes	TEST_START("new/free KEY_RSA1");
197276707Sdes	k1 = sshkey_new(KEY_RSA1);
198276707Sdes	ASSERT_PTR_NE(k1, NULL);
199276707Sdes	ASSERT_PTR_NE(k1->rsa, NULL);
200276707Sdes	ASSERT_PTR_NE(k1->rsa->n, NULL);
201276707Sdes	ASSERT_PTR_NE(k1->rsa->e, NULL);
202276707Sdes	ASSERT_PTR_EQ(k1->rsa->p, NULL);
203276707Sdes	sshkey_free(k1);
204276707Sdes	TEST_DONE();
205276707Sdes
206276707Sdes	TEST_START("new/free KEY_RSA");
207276707Sdes	k1 = sshkey_new(KEY_RSA);
208276707Sdes	ASSERT_PTR_NE(k1, NULL);
209276707Sdes	ASSERT_PTR_NE(k1->rsa, NULL);
210276707Sdes	ASSERT_PTR_NE(k1->rsa->n, NULL);
211276707Sdes	ASSERT_PTR_NE(k1->rsa->e, NULL);
212276707Sdes	ASSERT_PTR_EQ(k1->rsa->p, NULL);
213276707Sdes	sshkey_free(k1);
214276707Sdes	TEST_DONE();
215276707Sdes
216276707Sdes	TEST_START("new/free KEY_DSA");
217276707Sdes	k1 = sshkey_new(KEY_DSA);
218276707Sdes	ASSERT_PTR_NE(k1, NULL);
219276707Sdes	ASSERT_PTR_NE(k1->dsa, NULL);
220276707Sdes	ASSERT_PTR_NE(k1->dsa->g, NULL);
221276707Sdes	ASSERT_PTR_EQ(k1->dsa->priv_key, NULL);
222276707Sdes	sshkey_free(k1);
223276707Sdes	TEST_DONE();
224276707Sdes
225295367Sdes#ifdef OPENSSL_HAS_ECC
226276707Sdes	TEST_START("new/free KEY_ECDSA");
227276707Sdes	k1 = sshkey_new(KEY_ECDSA);
228276707Sdes	ASSERT_PTR_NE(k1, NULL);
229276707Sdes	ASSERT_PTR_EQ(k1->ecdsa, NULL);  /* Can't allocate without NID */
230276707Sdes	sshkey_free(k1);
231276707Sdes	TEST_DONE();
232295367Sdes#endif
233276707Sdes
234276707Sdes	TEST_START("new/free KEY_ED25519");
235276707Sdes	k1 = sshkey_new(KEY_ED25519);
236276707Sdes	ASSERT_PTR_NE(k1, NULL);
237276707Sdes	/* These should be blank until key loaded or generated */
238276707Sdes	ASSERT_PTR_EQ(k1->ed25519_sk, NULL);
239276707Sdes	ASSERT_PTR_EQ(k1->ed25519_pk, NULL);
240276707Sdes	sshkey_free(k1);
241276707Sdes	TEST_DONE();
242276707Sdes
243276707Sdes	TEST_START("new_private KEY_RSA");
244276707Sdes	k1 = sshkey_new_private(KEY_RSA);
245276707Sdes	ASSERT_PTR_NE(k1, NULL);
246276707Sdes	ASSERT_PTR_NE(k1->rsa, NULL);
247276707Sdes	ASSERT_PTR_NE(k1->rsa->n, NULL);
248276707Sdes	ASSERT_PTR_NE(k1->rsa->e, NULL);
249276707Sdes	ASSERT_PTR_NE(k1->rsa->p, NULL);
250276707Sdes	ASSERT_INT_EQ(sshkey_add_private(k1), 0);
251276707Sdes	sshkey_free(k1);
252276707Sdes	TEST_DONE();
253276707Sdes
254276707Sdes	TEST_START("new_private KEY_DSA");
255276707Sdes	k1 = sshkey_new_private(KEY_DSA);
256276707Sdes	ASSERT_PTR_NE(k1, NULL);
257276707Sdes	ASSERT_PTR_NE(k1->dsa, NULL);
258276707Sdes	ASSERT_PTR_NE(k1->dsa->g, NULL);
259276707Sdes	ASSERT_PTR_NE(k1->dsa->priv_key, NULL);
260276707Sdes	ASSERT_INT_EQ(sshkey_add_private(k1), 0);
261276707Sdes	sshkey_free(k1);
262276707Sdes	TEST_DONE();
263276707Sdes
264276707Sdes	TEST_START("generate KEY_RSA too small modulus");
265276707Sdes	ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 128, &k1),
266276707Sdes	    SSH_ERR_INVALID_ARGUMENT);
267276707Sdes	ASSERT_PTR_EQ(k1, NULL);
268276707Sdes	TEST_DONE();
269276707Sdes
270276707Sdes	TEST_START("generate KEY_RSA too large modulus");
271276707Sdes	ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1 << 20, &k1),
272276707Sdes	    SSH_ERR_INVALID_ARGUMENT);
273276707Sdes	ASSERT_PTR_EQ(k1, NULL);
274276707Sdes	TEST_DONE();
275276707Sdes
276276707Sdes	TEST_START("generate KEY_DSA wrong bits");
277276707Sdes	ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 2048, &k1),
278276707Sdes	    SSH_ERR_INVALID_ARGUMENT);
279276707Sdes	ASSERT_PTR_EQ(k1, NULL);
280276707Sdes	sshkey_free(k1);
281276707Sdes	TEST_DONE();
282276707Sdes
283295367Sdes#ifdef OPENSSL_HAS_ECC
284276707Sdes	TEST_START("generate KEY_ECDSA wrong bits");
285276707Sdes	ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1),
286276707Sdes	    SSH_ERR_INVALID_ARGUMENT);
287276707Sdes	ASSERT_PTR_EQ(k1, NULL);
288276707Sdes	sshkey_free(k1);
289276707Sdes	TEST_DONE();
290295367Sdes#endif
291276707Sdes
292276707Sdes	TEST_START("generate KEY_RSA");
293295367Sdes	ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 767, &kr),
294295367Sdes	    SSH_ERR_INVALID_ARGUMENT);
295295367Sdes	ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0);
296276707Sdes	ASSERT_PTR_NE(kr, NULL);
297276707Sdes	ASSERT_PTR_NE(kr->rsa, NULL);
298276707Sdes	ASSERT_PTR_NE(kr->rsa->n, NULL);
299276707Sdes	ASSERT_PTR_NE(kr->rsa->e, NULL);
300276707Sdes	ASSERT_PTR_NE(kr->rsa->p, NULL);
301295367Sdes	ASSERT_INT_EQ(BN_num_bits(kr->rsa->n), 1024);
302276707Sdes	TEST_DONE();
303276707Sdes
304276707Sdes	TEST_START("generate KEY_DSA");
305276707Sdes	ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0);
306276707Sdes	ASSERT_PTR_NE(kd, NULL);
307276707Sdes	ASSERT_PTR_NE(kd->dsa, NULL);
308276707Sdes	ASSERT_PTR_NE(kd->dsa->g, NULL);
309276707Sdes	ASSERT_PTR_NE(kd->dsa->priv_key, NULL);
310276707Sdes	TEST_DONE();
311276707Sdes
312276707Sdes#ifdef OPENSSL_HAS_ECC
313276707Sdes	TEST_START("generate KEY_ECDSA");
314276707Sdes	ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &ke), 0);
315276707Sdes	ASSERT_PTR_NE(ke, NULL);
316276707Sdes	ASSERT_PTR_NE(ke->ecdsa, NULL);
317276707Sdes	ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL);
318276707Sdes	ASSERT_PTR_NE(EC_KEY_get0_private_key(ke->ecdsa), NULL);
319276707Sdes	TEST_DONE();
320276707Sdes#endif
321276707Sdes
322276707Sdes	TEST_START("generate KEY_ED25519");
323276707Sdes	ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &kf), 0);
324276707Sdes	ASSERT_PTR_NE(kf, NULL);
325276707Sdes	ASSERT_INT_EQ(kf->type, KEY_ED25519);
326276707Sdes	ASSERT_PTR_NE(kf->ed25519_pk, NULL);
327276707Sdes	ASSERT_PTR_NE(kf->ed25519_sk, NULL);
328276707Sdes	TEST_DONE();
329276707Sdes
330276707Sdes	TEST_START("demote KEY_RSA");
331276707Sdes	ASSERT_INT_EQ(sshkey_demote(kr, &k1), 0);
332276707Sdes	ASSERT_PTR_NE(k1, NULL);
333276707Sdes	ASSERT_PTR_NE(kr, k1);
334276707Sdes	ASSERT_INT_EQ(k1->type, KEY_RSA);
335276707Sdes	ASSERT_PTR_NE(k1->rsa, NULL);
336276707Sdes	ASSERT_PTR_NE(k1->rsa->n, NULL);
337276707Sdes	ASSERT_PTR_NE(k1->rsa->e, NULL);
338276707Sdes	ASSERT_PTR_EQ(k1->rsa->p, NULL);
339276707Sdes	TEST_DONE();
340276707Sdes
341276707Sdes	TEST_START("equal KEY_RSA/demoted KEY_RSA");
342276707Sdes	ASSERT_INT_EQ(sshkey_equal(kr, k1), 1);
343276707Sdes	sshkey_free(k1);
344276707Sdes	TEST_DONE();
345276707Sdes
346276707Sdes	TEST_START("demote KEY_DSA");
347276707Sdes	ASSERT_INT_EQ(sshkey_demote(kd, &k1), 0);
348276707Sdes	ASSERT_PTR_NE(k1, NULL);
349276707Sdes	ASSERT_PTR_NE(kd, k1);
350276707Sdes	ASSERT_INT_EQ(k1->type, KEY_DSA);
351276707Sdes	ASSERT_PTR_NE(k1->dsa, NULL);
352276707Sdes	ASSERT_PTR_NE(k1->dsa->g, NULL);
353276707Sdes	ASSERT_PTR_EQ(k1->dsa->priv_key, NULL);
354276707Sdes	TEST_DONE();
355276707Sdes
356276707Sdes	TEST_START("equal KEY_DSA/demoted KEY_DSA");
357276707Sdes	ASSERT_INT_EQ(sshkey_equal(kd, k1), 1);
358276707Sdes	sshkey_free(k1);
359276707Sdes	TEST_DONE();
360276707Sdes
361276707Sdes#ifdef OPENSSL_HAS_ECC
362276707Sdes	TEST_START("demote KEY_ECDSA");
363276707Sdes	ASSERT_INT_EQ(sshkey_demote(ke, &k1), 0);
364276707Sdes	ASSERT_PTR_NE(k1, NULL);
365276707Sdes	ASSERT_PTR_NE(ke, k1);
366276707Sdes	ASSERT_INT_EQ(k1->type, KEY_ECDSA);
367276707Sdes	ASSERT_PTR_NE(k1->ecdsa, NULL);
368276707Sdes	ASSERT_INT_EQ(k1->ecdsa_nid, ke->ecdsa_nid);
369276707Sdes	ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL);
370276707Sdes	ASSERT_PTR_EQ(EC_KEY_get0_private_key(k1->ecdsa), NULL);
371276707Sdes	TEST_DONE();
372276707Sdes
373276707Sdes	TEST_START("equal KEY_ECDSA/demoted KEY_ECDSA");
374276707Sdes	ASSERT_INT_EQ(sshkey_equal(ke, k1), 1);
375276707Sdes	sshkey_free(k1);
376276707Sdes	TEST_DONE();
377276707Sdes#endif
378276707Sdes
379276707Sdes	TEST_START("demote KEY_ED25519");
380276707Sdes	ASSERT_INT_EQ(sshkey_demote(kf, &k1), 0);
381276707Sdes	ASSERT_PTR_NE(k1, NULL);
382276707Sdes	ASSERT_PTR_NE(kf, k1);
383276707Sdes	ASSERT_INT_EQ(k1->type, KEY_ED25519);
384276707Sdes	ASSERT_PTR_NE(k1->ed25519_pk, NULL);
385276707Sdes	ASSERT_PTR_EQ(k1->ed25519_sk, NULL);
386276707Sdes	TEST_DONE();
387276707Sdes
388276707Sdes	TEST_START("equal KEY_ED25519/demoted KEY_ED25519");
389276707Sdes	ASSERT_INT_EQ(sshkey_equal(kf, k1), 1);
390276707Sdes	sshkey_free(k1);
391276707Sdes	TEST_DONE();
392276707Sdes
393276707Sdes	TEST_START("equal mismatched key types");
394276707Sdes	ASSERT_INT_EQ(sshkey_equal(kd, kr), 0);
395276707Sdes#ifdef OPENSSL_HAS_ECC
396276707Sdes	ASSERT_INT_EQ(sshkey_equal(kd, ke), 0);
397276707Sdes	ASSERT_INT_EQ(sshkey_equal(kr, ke), 0);
398276707Sdes	ASSERT_INT_EQ(sshkey_equal(ke, kf), 0);
399276707Sdes#endif
400276707Sdes	ASSERT_INT_EQ(sshkey_equal(kd, kf), 0);
401276707Sdes	TEST_DONE();
402276707Sdes
403276707Sdes	TEST_START("equal different keys");
404295367Sdes	ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &k1), 0);
405276707Sdes	ASSERT_INT_EQ(sshkey_equal(kr, k1), 0);
406276707Sdes	sshkey_free(k1);
407276707Sdes	ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &k1), 0);
408276707Sdes	ASSERT_INT_EQ(sshkey_equal(kd, k1), 0);
409276707Sdes	sshkey_free(k1);
410276707Sdes#ifdef OPENSSL_HAS_ECC
411276707Sdes	ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &k1), 0);
412276707Sdes	ASSERT_INT_EQ(sshkey_equal(ke, k1), 0);
413276707Sdes	sshkey_free(k1);
414276707Sdes#endif
415276707Sdes	ASSERT_INT_EQ(sshkey_generate(KEY_ED25519, 256, &k1), 0);
416276707Sdes	ASSERT_INT_EQ(sshkey_equal(kf, k1), 0);
417276707Sdes	sshkey_free(k1);
418276707Sdes	TEST_DONE();
419276707Sdes
420276707Sdes	sshkey_free(kr);
421276707Sdes	sshkey_free(kd);
422276707Sdes#ifdef OPENSSL_HAS_ECC
423276707Sdes	sshkey_free(ke);
424276707Sdes#endif
425276707Sdes	sshkey_free(kf);
426276707Sdes
427295367Sdes	TEST_START("certify key");
428295367Sdes	ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_1.pub"),
429295367Sdes	    &k1, NULL), 0);
430295367Sdes	k2 = get_private("ed25519_2");
431295367Sdes	ASSERT_INT_EQ(sshkey_to_certified(k1), 0);
432295367Sdes	ASSERT_PTR_NE(k1->cert, NULL);
433295367Sdes	k1->cert->type = SSH2_CERT_TYPE_USER;
434295367Sdes	k1->cert->serial = 1234;
435295367Sdes	k1->cert->key_id = strdup("estragon");
436295367Sdes	ASSERT_PTR_NE(k1->cert->key_id, NULL);
437295367Sdes	k1->cert->principals = calloc(4, sizeof(*k1->cert->principals));
438295367Sdes	ASSERT_PTR_NE(k1->cert->principals, NULL);
439295367Sdes	k1->cert->principals[0] = strdup("estragon");
440295367Sdes	k1->cert->principals[1] = strdup("vladimir");
441295367Sdes	k1->cert->principals[2] = strdup("pozzo");
442295367Sdes	k1->cert->principals[3] = strdup("lucky");
443295367Sdes	ASSERT_PTR_NE(k1->cert->principals[0], NULL);
444295367Sdes	ASSERT_PTR_NE(k1->cert->principals[1], NULL);
445295367Sdes	ASSERT_PTR_NE(k1->cert->principals[2], NULL);
446295367Sdes	ASSERT_PTR_NE(k1->cert->principals[3], NULL);
447295367Sdes	k1->cert->valid_after = 0;
448295367Sdes	k1->cert->valid_before = (u_int64_t)-1;
449295367Sdes	k1->cert->critical = sshbuf_new();
450295367Sdes	ASSERT_PTR_NE(k1->cert->critical, NULL);
451295367Sdes	k1->cert->extensions = sshbuf_new();
452295367Sdes	ASSERT_PTR_NE(k1->cert->extensions, NULL);
453295367Sdes	put_opt(k1->cert->critical, "force-command", "/usr/bin/true");
454295367Sdes	put_opt(k1->cert->critical, "source-address", "127.0.0.1");
455295367Sdes	put_opt(k1->cert->extensions, "permit-X11-forwarding", NULL);
456295367Sdes	put_opt(k1->cert->extensions, "permit-agent-forwarding", NULL);
457295367Sdes	ASSERT_INT_EQ(sshkey_from_private(k2, &k1->cert->signature_key), 0);
458323124Sdes	ASSERT_INT_EQ(sshkey_certify(k1, k2, NULL), 0);
459295367Sdes	b = sshbuf_new();
460295367Sdes	ASSERT_PTR_NE(b, NULL);
461295367Sdes	ASSERT_INT_EQ(sshkey_putb(k1, b), 0);
462295367Sdes	ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k3), 0);
463276707Sdes
464295367Sdes	sshkey_free(k1);
465295367Sdes	sshkey_free(k2);
466295367Sdes	sshkey_free(k3);
467295367Sdes	sshbuf_reset(b);
468295367Sdes	TEST_DONE();
469295367Sdes
470295367Sdes	TEST_START("sign and verify RSA");
471295367Sdes	k1 = get_private("rsa_1");
472295367Sdes	ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2,
473295367Sdes	    NULL), 0);
474296781Sdes	signature_tests(k1, k2, "ssh-rsa");
475295367Sdes	sshkey_free(k1);
476295367Sdes	sshkey_free(k2);
477295367Sdes	TEST_DONE();
478295367Sdes
479296781Sdes	TEST_START("sign and verify RSA-SHA256");
480296781Sdes	k1 = get_private("rsa_1");
481296781Sdes	ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2,
482296781Sdes	    NULL), 0);
483296781Sdes	signature_tests(k1, k2, "rsa-sha2-256");
484296781Sdes	sshkey_free(k1);
485296781Sdes	sshkey_free(k2);
486296781Sdes	TEST_DONE();
487296781Sdes
488296781Sdes	TEST_START("sign and verify RSA-SHA512");
489296781Sdes	k1 = get_private("rsa_1");
490296781Sdes	ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2,
491296781Sdes	    NULL), 0);
492296781Sdes	signature_tests(k1, k2, "rsa-sha2-512");
493296781Sdes	sshkey_free(k1);
494296781Sdes	sshkey_free(k2);
495296781Sdes	TEST_DONE();
496296781Sdes
497295367Sdes	TEST_START("sign and verify DSA");
498295367Sdes	k1 = get_private("dsa_1");
499295367Sdes	ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_2.pub"), &k2,
500295367Sdes	    NULL), 0);
501296781Sdes	signature_tests(k1, k2, NULL);
502295367Sdes	sshkey_free(k1);
503295367Sdes	sshkey_free(k2);
504295367Sdes	TEST_DONE();
505295367Sdes
506295367Sdes#ifdef OPENSSL_HAS_ECC
507295367Sdes	TEST_START("sign and verify ECDSA");
508295367Sdes	k1 = get_private("ecdsa_1");
509295367Sdes	ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_2.pub"), &k2,
510295367Sdes	    NULL), 0);
511296781Sdes	signature_tests(k1, k2, NULL);
512295367Sdes	sshkey_free(k1);
513295367Sdes	sshkey_free(k2);
514295367Sdes	TEST_DONE();
515295367Sdes#endif
516295367Sdes
517295367Sdes	TEST_START("sign and verify ED25519");
518295367Sdes	k1 = get_private("ed25519_1");
519295367Sdes	ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_2.pub"), &k2,
520295367Sdes	    NULL), 0);
521296781Sdes	signature_tests(k1, k2, NULL);
522295367Sdes	sshkey_free(k1);
523295367Sdes	sshkey_free(k2);
524295367Sdes	TEST_DONE();
525295367Sdes
526276707Sdes	TEST_START("nested certificate");
527276707Sdes	ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0);
528276707Sdes	ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2,
529276707Sdes	    NULL), 0);
530295367Sdes	k3 = get_private("rsa_1");
531296781Sdes	build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1, NULL);
532276707Sdes	ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4),
533276707Sdes	    SSH_ERR_KEY_CERT_INVALID_SIGN_KEY);
534276707Sdes	ASSERT_PTR_EQ(k4, NULL);
535276707Sdes	sshkey_free(k1);
536276707Sdes	sshkey_free(k2);
537276707Sdes	sshkey_free(k3);
538295367Sdes	sshbuf_free(b);
539276707Sdes	TEST_DONE();
540276707Sdes
541276707Sdes}
542