xref: /freebsd/crypto/openssh/regress/misc/fuzz-harness/agent_fuzz_helper.c (revision 2a58b312b62f908ec92311d1bd8536dbaeb8e55b)
1 #include "fixed-keys.h"
2 #include <assert.h>
3 
4 #define main(ac, av) xxxmain(ac, av)
5 #include "../../../ssh-agent.c"
6 
7 void test_one(const uint8_t* s, size_t slen);
8 
9 static int
10 devnull_or_die(void)
11 {
12 	int fd;
13 
14 	if ((fd = open("/dev/null", O_RDWR)) == -1) {
15 		error_f("open /dev/null: %s", strerror(errno));
16 		abort();
17 	}
18 	return fd;
19 }
20 
21 static struct sshkey *
22 pubkey_or_die(const char *s)
23 {
24 	char *tmp, *cp;
25 	struct sshkey *pubkey;
26 	int r;
27 
28 	tmp = cp = xstrdup(s);
29 	if ((pubkey = sshkey_new(KEY_UNSPEC)) == NULL)
30 		abort();
31 	if ((r = sshkey_read(pubkey, &cp)) != 0) {
32 		error_fr(r, "parse");
33 		abort();
34 	}
35 	free(tmp);
36 	return pubkey;
37 }
38 
39 static struct sshkey *
40 privkey_or_die(const char *s)
41 {
42 	int r;
43 	struct sshbuf *b;
44 	struct sshkey *privkey;
45 
46 	if ((b = sshbuf_from(s, strlen(s))) == NULL) {
47 		error_f("sshbuf_from failed");
48 		abort();
49 	}
50 	if ((r = sshkey_parse_private_fileblob(b, "", &privkey, NULL)) != 0) {
51 		error_fr(r, "parse");
52 		abort();
53 	}
54 	sshbuf_free(b);
55 	return privkey;
56 }
57 
58 static void
59 add_key(const char *privkey, const char *certpath)
60 {
61 	Identity *id;
62 	int r;
63 	struct sshkey *cert;
64 
65 	id = xcalloc(1, sizeof(Identity));
66 	TAILQ_INSERT_TAIL(&idtab->idlist, id, next);
67 	idtab->nentries++;
68 	id->key = privkey_or_die(privkey);
69 	id->comment = xstrdup("rhododaktulos Eos");
70 	if (sshkey_is_sk(id->key))
71 		id->sk_provider = xstrdup("internal");
72 
73 	/* Now the cert too */
74 	id = xcalloc(1, sizeof(Identity));
75 	TAILQ_INSERT_TAIL(&idtab->idlist, id, next);
76 	idtab->nentries++;
77 	id->key = privkey_or_die(privkey);
78 	cert = pubkey_or_die(certpath);
79 	if ((r = sshkey_to_certified(id->key)) != 0) {
80 		error_fr(r, "sshkey_to_certified");
81 		abort();
82 	}
83 	if ((r = sshkey_cert_copy(cert, id->key)) != 0) {
84 		error_fr(r, "sshkey_cert_copy");
85 		abort();
86 	}
87 	sshkey_free(cert);
88 	id->comment = xstrdup("outis");
89 	if (sshkey_is_sk(id->key))
90 		id->sk_provider = xstrdup("internal");
91 }
92 
93 static void
94 cleanup_idtab(void)
95 {
96 	Identity *id;
97 
98 	if (idtab == NULL) return;
99 	for (id = TAILQ_FIRST(&idtab->idlist); id;
100 	    id = TAILQ_FIRST(&idtab->idlist)) {
101 		TAILQ_REMOVE(&idtab->idlist, id, next);
102 		free_identity(id);
103 	}
104 	free(idtab);
105 	idtab = NULL;
106 }
107 
108 static void
109 reset_idtab(void)
110 {
111 	cleanup_idtab();
112 	idtab_init();
113 	// Load keys.
114 	add_key(PRIV_RSA, CERT_RSA);
115 	add_key(PRIV_DSA, CERT_DSA);
116 	add_key(PRIV_ECDSA, CERT_ECDSA);
117 	add_key(PRIV_ED25519, CERT_ED25519);
118 	add_key(PRIV_ECDSA_SK, CERT_ECDSA_SK);
119 	add_key(PRIV_ED25519_SK, CERT_ED25519_SK);
120 }
121 
122 static void
123 cleanup_sockettab(void)
124 {
125 	u_int i;
126 	for (i = 0; i < sockets_alloc; i++) {
127 		if (sockets[i].type != AUTH_UNUSED)
128 			close_socket(sockets + i);
129 	}
130 	free(sockets);
131 	sockets = NULL;
132 	sockets_alloc = 0;
133 }
134 
135 static void
136 reset_sockettab(int devnull)
137 {
138 	int fd;
139 
140 	cleanup_sockettab();
141 	if ((fd = dup(devnull)) == -1) {
142 		error_f("dup: %s", strerror(errno));
143 		abort();
144 	}
145 	new_socket(AUTH_CONNECTION, fd);
146 	assert(sockets[0].type == AUTH_CONNECTION);
147 	assert(sockets[0].fd == fd);
148 }
149 
150 #define MAX_MESSAGES 256
151 void
152 test_one(const uint8_t* s, size_t slen)
153 {
154 	static int devnull = -1;
155 	size_t i, olen, nlen;
156 
157 	if (devnull == -1) {
158 		log_init(__progname, SYSLOG_LEVEL_DEBUG3,
159 		    SYSLOG_FACILITY_AUTH, 1);
160 		devnull = devnull_or_die();
161 		allowed_providers = xstrdup("");
162 		setenv("DISPLAY", "", 1); /* ban askpass */
163 	}
164 
165 	reset_idtab();
166 	reset_sockettab(devnull);
167 	(void)sshbuf_put(sockets[0].input, s, slen);
168 	for (i = 0; i < MAX_MESSAGES; i++) {
169 		olen = sshbuf_len(sockets[0].input);
170 		process_message(0);
171 		nlen = sshbuf_len(sockets[0].input);
172 		if (nlen == 0 || nlen == olen)
173 			break;
174 	}
175 	cleanup_idtab();
176 	cleanup_sockettab();
177 }
178