diff options
author | Colin Watson <cjwatson@debian.org> | 2019-06-05 06:41:44 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2019-06-09 22:09:07 +0100 |
commit | 865a97e05b6aab1619e1c8eeb33ccb8f9a9e48d3 (patch) | |
tree | 7bb2128eb663180bacfabca88f26d26bf0733824 /ssh-pkcs11-helper.c | |
parent | ba627ba172d6649919baedff5ba2789610da382a (diff) | |
parent | 7d50f9e5be88179325983a1f58c9d51bb58f025a (diff) |
New upstream release (8.0p1)
Diffstat (limited to 'ssh-pkcs11-helper.c')
-rw-r--r-- | ssh-pkcs11-helper.c | 106 |
1 files changed, 70 insertions, 36 deletions
diff --git a/ssh-pkcs11-helper.c b/ssh-pkcs11-helper.c index 6301033c5..97fb1212c 100644 --- a/ssh-pkcs11-helper.c +++ b/ssh-pkcs11-helper.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-pkcs11-helper.c,v 1.14 2018/01/08 15:18:46 markus Exp $ */ | 1 | /* $OpenBSD: ssh-pkcs11-helper.c,v 1.17 2019/01/23 02:01:10 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2010 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2010 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -24,10 +24,11 @@ | |||
24 | 24 | ||
25 | #include "openbsd-compat/sys-queue.h" | 25 | #include "openbsd-compat/sys-queue.h" |
26 | 26 | ||
27 | #include <errno.h> | ||
28 | #include <poll.h> | ||
27 | #include <stdarg.h> | 29 | #include <stdarg.h> |
28 | #include <string.h> | 30 | #include <string.h> |
29 | #include <unistd.h> | 31 | #include <unistd.h> |
30 | #include <errno.h> | ||
31 | 32 | ||
32 | #include "xmalloc.h" | 33 | #include "xmalloc.h" |
33 | #include "sshbuf.h" | 34 | #include "sshbuf.h" |
@@ -110,7 +111,7 @@ static void | |||
110 | process_add(void) | 111 | process_add(void) |
111 | { | 112 | { |
112 | char *name, *pin; | 113 | char *name, *pin; |
113 | struct sshkey **keys; | 114 | struct sshkey **keys = NULL; |
114 | int r, i, nkeys; | 115 | int r, i, nkeys; |
115 | u_char *blob; | 116 | u_char *blob; |
116 | size_t blen; | 117 | size_t blen; |
@@ -139,11 +140,13 @@ process_add(void) | |||
139 | free(blob); | 140 | free(blob); |
140 | add_key(keys[i], name); | 141 | add_key(keys[i], name); |
141 | } | 142 | } |
142 | free(keys); | ||
143 | } else { | 143 | } else { |
144 | if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0) | 144 | if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0) |
145 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 145 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
146 | if ((r = sshbuf_put_u32(msg, -nkeys)) != 0) | ||
147 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
146 | } | 148 | } |
149 | free(keys); | ||
147 | free(pin); | 150 | free(pin); |
148 | free(name); | 151 | free(name); |
149 | send_msg(msg); | 152 | send_msg(msg); |
@@ -192,15 +195,33 @@ process_sign(void) | |||
192 | else { | 195 | else { |
193 | if ((found = lookup_key(key)) != NULL) { | 196 | if ((found = lookup_key(key)) != NULL) { |
194 | #ifdef WITH_OPENSSL | 197 | #ifdef WITH_OPENSSL |
198 | u_int xslen; | ||
195 | int ret; | 199 | int ret; |
196 | 200 | ||
197 | slen = RSA_size(key->rsa); | 201 | if (key->type == KEY_RSA) { |
198 | signature = xmalloc(slen); | 202 | slen = RSA_size(key->rsa); |
199 | if ((ret = RSA_private_encrypt(dlen, data, signature, | 203 | signature = xmalloc(slen); |
200 | found->rsa, RSA_PKCS1_PADDING)) != -1) { | 204 | ret = RSA_private_encrypt(dlen, data, signature, |
201 | slen = ret; | 205 | found->rsa, RSA_PKCS1_PADDING); |
202 | ok = 0; | 206 | if (ret != -1) { |
203 | } | 207 | slen = ret; |
208 | ok = 0; | ||
209 | } | ||
210 | } else if (key->type == KEY_ECDSA) { | ||
211 | xslen = ECDSA_size(key->ecdsa); | ||
212 | signature = xmalloc(xslen); | ||
213 | /* "The parameter type is ignored." */ | ||
214 | ret = ECDSA_sign(-1, data, dlen, signature, | ||
215 | &xslen, found->ecdsa); | ||
216 | if (ret != 0) | ||
217 | ok = 0; | ||
218 | else | ||
219 | error("%s: ECDSA_sign" | ||
220 | " returns %d", __func__, ret); | ||
221 | slen = xslen; | ||
222 | } else | ||
223 | error("%s: don't know how to sign with key " | ||
224 | "type %d", __func__, (int)key->type); | ||
204 | #endif /* WITH_OPENSSL */ | 225 | #endif /* WITH_OPENSSL */ |
205 | } | 226 | } |
206 | sshkey_free(key); | 227 | sshkey_free(key); |
@@ -287,27 +308,44 @@ cleanup_exit(int i) | |||
287 | _exit(i); | 308 | _exit(i); |
288 | } | 309 | } |
289 | 310 | ||
311 | |||
290 | int | 312 | int |
291 | main(int argc, char **argv) | 313 | main(int argc, char **argv) |
292 | { | 314 | { |
293 | fd_set *rset, *wset; | 315 | int r, ch, in, out, max, log_stderr = 0; |
294 | int r, in, out, max, log_stderr = 0; | 316 | ssize_t len; |
295 | ssize_t len, olen, set_size; | ||
296 | SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; | 317 | SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; |
297 | LogLevel log_level = SYSLOG_LEVEL_ERROR; | 318 | LogLevel log_level = SYSLOG_LEVEL_ERROR; |
298 | char buf[4*4096]; | 319 | char buf[4*4096]; |
299 | |||
300 | extern char *__progname; | 320 | extern char *__progname; |
321 | struct pollfd pfd[2]; | ||
301 | 322 | ||
302 | ssh_malloc_init(); /* must be called before any mallocs */ | 323 | ssh_malloc_init(); /* must be called before any mallocs */ |
324 | __progname = ssh_get_progname(argv[0]); | ||
325 | seed_rng(); | ||
303 | TAILQ_INIT(&pkcs11_keylist); | 326 | TAILQ_INIT(&pkcs11_keylist); |
304 | pkcs11_init(0); | ||
305 | 327 | ||
306 | seed_rng(); | 328 | log_init(__progname, log_level, log_facility, log_stderr); |
307 | __progname = ssh_get_progname(argv[0]); | 329 | |
330 | while ((ch = getopt(argc, argv, "v")) != -1) { | ||
331 | switch (ch) { | ||
332 | case 'v': | ||
333 | log_stderr = 1; | ||
334 | if (log_level == SYSLOG_LEVEL_ERROR) | ||
335 | log_level = SYSLOG_LEVEL_DEBUG1; | ||
336 | else if (log_level < SYSLOG_LEVEL_DEBUG3) | ||
337 | log_level++; | ||
338 | break; | ||
339 | default: | ||
340 | fprintf(stderr, "usage: %s [-v]\n", __progname); | ||
341 | exit(1); | ||
342 | } | ||
343 | } | ||
308 | 344 | ||
309 | log_init(__progname, log_level, log_facility, log_stderr); | 345 | log_init(__progname, log_level, log_facility, log_stderr); |
310 | 346 | ||
347 | pkcs11_init(0); | ||
348 | |||
311 | in = STDIN_FILENO; | 349 | in = STDIN_FILENO; |
312 | out = STDOUT_FILENO; | 350 | out = STDOUT_FILENO; |
313 | 351 | ||
@@ -322,13 +360,10 @@ main(int argc, char **argv) | |||
322 | if ((oqueue = sshbuf_new()) == NULL) | 360 | if ((oqueue = sshbuf_new()) == NULL) |
323 | fatal("%s: sshbuf_new failed", __func__); | 361 | fatal("%s: sshbuf_new failed", __func__); |
324 | 362 | ||
325 | set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask); | 363 | while (1) { |
326 | rset = xmalloc(set_size); | 364 | memset(pfd, 0, sizeof(pfd)); |
327 | wset = xmalloc(set_size); | 365 | pfd[0].fd = in; |
328 | 366 | pfd[1].fd = out; | |
329 | for (;;) { | ||
330 | memset(rset, 0, set_size); | ||
331 | memset(wset, 0, set_size); | ||
332 | 367 | ||
333 | /* | 368 | /* |
334 | * Ensure that we can read a full buffer and handle | 369 | * Ensure that we can read a full buffer and handle |
@@ -337,23 +372,21 @@ main(int argc, char **argv) | |||
337 | */ | 372 | */ |
338 | if ((r = sshbuf_check_reserve(iqueue, sizeof(buf))) == 0 && | 373 | if ((r = sshbuf_check_reserve(iqueue, sizeof(buf))) == 0 && |
339 | (r = sshbuf_check_reserve(oqueue, MAX_MSG_LENGTH)) == 0) | 374 | (r = sshbuf_check_reserve(oqueue, MAX_MSG_LENGTH)) == 0) |
340 | FD_SET(in, rset); | 375 | pfd[0].events = POLLIN; |
341 | else if (r != SSH_ERR_NO_BUFFER_SPACE) | 376 | else if (r != SSH_ERR_NO_BUFFER_SPACE) |
342 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 377 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
343 | 378 | ||
344 | olen = sshbuf_len(oqueue); | 379 | if (sshbuf_len(oqueue) > 0) |
345 | if (olen > 0) | 380 | pfd[1].events = POLLOUT; |
346 | FD_SET(out, wset); | ||
347 | 381 | ||
348 | if (select(max+1, rset, wset, NULL, NULL) < 0) { | 382 | if ((r = poll(pfd, 2, -1 /* INFTIM */)) <= 0) { |
349 | if (errno == EINTR) | 383 | if (r == 0 || errno == EINTR) |
350 | continue; | 384 | continue; |
351 | error("select: %s", strerror(errno)); | 385 | fatal("poll: %s", strerror(errno)); |
352 | cleanup_exit(2); | ||
353 | } | 386 | } |
354 | 387 | ||
355 | /* copy stdin to iqueue */ | 388 | /* copy stdin to iqueue */ |
356 | if (FD_ISSET(in, rset)) { | 389 | if ((pfd[0].revents & (POLLIN|POLLERR)) != 0) { |
357 | len = read(in, buf, sizeof buf); | 390 | len = read(in, buf, sizeof buf); |
358 | if (len == 0) { | 391 | if (len == 0) { |
359 | debug("read eof"); | 392 | debug("read eof"); |
@@ -367,8 +400,9 @@ main(int argc, char **argv) | |||
367 | } | 400 | } |
368 | } | 401 | } |
369 | /* send oqueue to stdout */ | 402 | /* send oqueue to stdout */ |
370 | if (FD_ISSET(out, wset)) { | 403 | if ((pfd[1].revents & (POLLOUT|POLLHUP)) != 0) { |
371 | len = write(out, sshbuf_ptr(oqueue), olen); | 404 | len = write(out, sshbuf_ptr(oqueue), |
405 | sshbuf_len(oqueue)); | ||
372 | if (len < 0) { | 406 | if (len < 0) { |
373 | error("write: %s", strerror(errno)); | 407 | error("write: %s", strerror(errno)); |
374 | cleanup_exit(1); | 408 | cleanup_exit(1); |