summaryrefslogtreecommitdiff
path: root/ssh-agent.c
diff options
context:
space:
mode:
authormarkus@openbsd.org <markus@openbsd.org>2015-01-14 13:09:09 +0000
committerDamien Miller <djm@mindrot.org>2015-01-15 02:22:17 +1100
commit139ca81866ec1b219c717d17061e5e7ad1059e2a (patch)
treefdb4cbb68947ff4231dc7a003c28525537816afa /ssh-agent.c
parent81bfbd0bd35683de5d7f2238b985e5f8150a9180 (diff)
upstream commit
switch to sshbuf/sshkey; with & ok djm@
Diffstat (limited to 'ssh-agent.c')
-rw-r--r--ssh-agent.c520
1 files changed, 308 insertions, 212 deletions
diff --git a/ssh-agent.c b/ssh-agent.c
index ae2bacca5..4925d47a3 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.193 2014/12/21 23:35:14 jmc Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.194 2015/01/14 13:09:09 markus Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -67,16 +67,20 @@
67#include <string.h> 67#include <string.h>
68#include <unistd.h> 68#include <unistd.h>
69 69
70#include "key.h" /* XXX for typedef */
71#include "buffer.h" /* XXX for typedef */
72
70#include "xmalloc.h" 73#include "xmalloc.h"
71#include "ssh.h" 74#include "ssh.h"
72#include "rsa.h" 75#include "rsa.h"
73#include "buffer.h" 76#include "sshbuf.h"
74#include "key.h" 77#include "sshkey.h"
75#include "authfd.h" 78#include "authfd.h"
76#include "compat.h" 79#include "compat.h"
77#include "log.h" 80#include "log.h"
78#include "misc.h" 81#include "misc.h"
79#include "digest.h" 82#include "digest.h"
83#include "ssherr.h"
80 84
81#ifdef ENABLE_PKCS11 85#ifdef ENABLE_PKCS11
82#include "ssh-pkcs11.h" 86#include "ssh-pkcs11.h"
@@ -95,9 +99,9 @@ typedef enum {
95typedef struct { 99typedef struct {
96 int fd; 100 int fd;
97 sock_type type; 101 sock_type type;
98 Buffer input; 102 struct sshbuf *input;
99 Buffer output; 103 struct sshbuf *output;
100 Buffer request; 104 struct sshbuf *request;
101} SocketEntry; 105} SocketEntry;
102 106
103u_int sockets_alloc = 0; 107u_int sockets_alloc = 0;
@@ -105,7 +109,7 @@ SocketEntry *sockets = NULL;
105 109
106typedef struct identity { 110typedef struct identity {
107 TAILQ_ENTRY(identity) next; 111 TAILQ_ENTRY(identity) next;
108 Key *key; 112 struct sshkey *key;
109 char *comment; 113 char *comment;
110 char *provider; 114 char *provider;
111 time_t death; 115 time_t death;
@@ -150,9 +154,9 @@ close_socket(SocketEntry *e)
150 close(e->fd); 154 close(e->fd);
151 e->fd = -1; 155 e->fd = -1;
152 e->type = AUTH_UNUSED; 156 e->type = AUTH_UNUSED;
153 buffer_free(&e->input); 157 sshbuf_free(e->input);
154 buffer_free(&e->output); 158 sshbuf_free(e->output);
155 buffer_free(&e->request); 159 sshbuf_free(e->request);
156} 160}
157 161
158static void 162static void
@@ -178,7 +182,7 @@ idtab_lookup(int version)
178static void 182static void
179free_identity(Identity *id) 183free_identity(Identity *id)
180{ 184{
181 key_free(id->key); 185 sshkey_free(id->key);
182 free(id->provider); 186 free(id->provider);
183 free(id->comment); 187 free(id->comment);
184 free(id); 188 free(id);
@@ -186,13 +190,13 @@ free_identity(Identity *id)
186 190
187/* return matching private key for given public key */ 191/* return matching private key for given public key */
188static Identity * 192static Identity *
189lookup_identity(Key *key, int version) 193lookup_identity(struct sshkey *key, int version)
190{ 194{
191 Identity *id; 195 Identity *id;
192 196
193 Idtab *tab = idtab_lookup(version); 197 Idtab *tab = idtab_lookup(version);
194 TAILQ_FOREACH(id, &tab->idlist, next) { 198 TAILQ_FOREACH(id, &tab->idlist, next) {
195 if (key_equal(key, id->key)) 199 if (sshkey_equal(key, id->key))
196 return (id); 200 return (id);
197 } 201 }
198 return (NULL); 202 return (NULL);
@@ -205,7 +209,7 @@ confirm_key(Identity *id)
205 char *p; 209 char *p;
206 int ret = -1; 210 int ret = -1;
207 211
208 p = key_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT); 212 p = sshkey_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT);
209 if (ask_permission("Allow use of key %s?\nKey fingerprint %s.", 213 if (ask_permission("Allow use of key %s?\nKey fingerprint %s.",
210 id->comment, p)) 214 id->comment, p))
211 ret = 0; 215 ret = 0;
@@ -214,37 +218,65 @@ confirm_key(Identity *id)
214 return (ret); 218 return (ret);
215} 219}
216 220
221static void
222send_status(SocketEntry *e, int success)
223{
224 int r;
225
226 if ((r = sshbuf_put_u32(e->output, 1)) != 0 ||
227 (r = sshbuf_put_u8(e->output, success ?
228 SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE)) != 0)
229 fatal("%s: buffer error: %s", __func__, ssh_err(r));
230}
231
217/* send list of supported public keys to 'client' */ 232/* send list of supported public keys to 'client' */
218static void 233static void
219process_request_identities(SocketEntry *e, int version) 234process_request_identities(SocketEntry *e, int version)
220{ 235{
221 Idtab *tab = idtab_lookup(version); 236 Idtab *tab = idtab_lookup(version);
222 Identity *id; 237 Identity *id;
223 Buffer msg; 238 struct sshbuf *msg;
224 239 int r;
225 buffer_init(&msg); 240
226 buffer_put_char(&msg, (version == 1) ? 241 if ((msg = sshbuf_new()) == NULL)
227 SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER); 242 fatal("%s: sshbuf_new failed", __func__);
228 buffer_put_int(&msg, tab->nentries); 243 if ((r = sshbuf_put_u8(msg, (version == 1) ?
244 SSH_AGENT_RSA_IDENTITIES_ANSWER :
245 SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
246 (r = sshbuf_put_u32(msg, tab->nentries)) != 0)
247 fatal("%s: buffer error: %s", __func__, ssh_err(r));
229 TAILQ_FOREACH(id, &tab->idlist, next) { 248 TAILQ_FOREACH(id, &tab->idlist, next) {
230 if (id->key->type == KEY_RSA1) { 249 if (id->key->type == KEY_RSA1) {
231#ifdef WITH_SSH1 250#ifdef WITH_SSH1
232 buffer_put_int(&msg, BN_num_bits(id->key->rsa->n)); 251 if ((r = sshbuf_put_u32(msg,
233 buffer_put_bignum(&msg, id->key->rsa->e); 252 BN_num_bits(id->key->rsa->n))) != 0 ||
234 buffer_put_bignum(&msg, id->key->rsa->n); 253 (r = sshbuf_put_bignum1(msg,
254 id->key->rsa->e)) != 0 ||
255 (r = sshbuf_put_bignum1(msg,
256 id->key->rsa->n)) != 0)
257 fatal("%s: buffer error: %s",
258 __func__, ssh_err(r));
235#endif 259#endif
236 } else { 260 } else {
237 u_char *blob; 261 u_char *blob;
238 u_int blen; 262 size_t blen;
239 key_to_blob(id->key, &blob, &blen); 263
240 buffer_put_string(&msg, blob, blen); 264 if ((r = sshkey_to_blob(id->key, &blob, &blen)) != 0) {
265 error("%s: sshkey_to_blob: %s", __func__,
266 ssh_err(r));
267 continue;
268 }
269 if ((r = sshbuf_put_string(msg, blob, blen)) != 0)
270 fatal("%s: buffer error: %s",
271 __func__, ssh_err(r));
241 free(blob); 272 free(blob);
242 } 273 }
243 buffer_put_cstring(&msg, id->comment); 274 if ((r = sshbuf_put_cstring(msg, id->comment)) != 0)
275 fatal("%s: buffer error: %s", __func__, ssh_err(r));
244 } 276 }
245 buffer_put_int(&e->output, buffer_len(&msg)); 277 if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
246 buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); 278 fatal("%s: buffer error: %s", __func__, ssh_err(r));
247 buffer_free(&msg); 279 sshbuf_free(msg);
248} 280}
249 281
250#ifdef WITH_SSH1 282#ifdef WITH_SSH1
@@ -256,40 +288,48 @@ process_authentication_challenge1(SocketEntry *e)
256 u_int response_type; 288 u_int response_type;
257 BIGNUM *challenge; 289 BIGNUM *challenge;
258 Identity *id; 290 Identity *id;
259 int i, len; 291 int r, len;
260 Buffer msg; 292 struct sshbuf *msg;
261 struct ssh_digest_ctx *md; 293 struct ssh_digest_ctx *md;
262 Key *key; 294 struct sshkey *key;
263 295
264 buffer_init(&msg); 296 if ((msg = sshbuf_new()) == NULL)
265 key = key_new(KEY_RSA1); 297 fatal("%s: sshbuf_new failed", __func__);
298 if ((key = sshkey_new(KEY_RSA1)) == NULL)
299 fatal("%s: sshkey_new failed", __func__);
266 if ((challenge = BN_new()) == NULL) 300 if ((challenge = BN_new()) == NULL)
267 fatal("process_authentication_challenge1: BN_new failed"); 301 fatal("%s: BN_new failed", __func__);
268 302
269 (void) buffer_get_int(&e->request); /* ignored */ 303 if ((r = sshbuf_get_u32(e->request, NULL)) != 0 || /* ignored */
270 buffer_get_bignum(&e->request, key->rsa->e); 304 (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 ||
271 buffer_get_bignum(&e->request, key->rsa->n); 305 (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0 ||
272 buffer_get_bignum(&e->request, challenge); 306 (r = sshbuf_get_bignum1(e->request, challenge)))
307 fatal("%s: buffer error: %s", __func__, ssh_err(r));
273 308
274 /* Only protocol 1.1 is supported */ 309 /* Only protocol 1.1 is supported */
275 if (buffer_len(&e->request) == 0) 310 if (sshbuf_len(e->request) == 0)
276 goto failure; 311 goto failure;
277 buffer_get(&e->request, session_id, 16); 312 if ((r = sshbuf_get(e->request, session_id, sizeof(session_id))) != 0 ||
278 response_type = buffer_get_int(&e->request); 313 (r = sshbuf_get_u32(e->request, &response_type)) != 0)
314 fatal("%s: buffer error: %s", __func__, ssh_err(r));
279 if (response_type != 1) 315 if (response_type != 1)
280 goto failure; 316 goto failure;
281 317
282 id = lookup_identity(key, 1); 318 id = lookup_identity(key, 1);
283 if (id != NULL && (!id->confirm || confirm_key(id) == 0)) { 319 if (id != NULL && (!id->confirm || confirm_key(id) == 0)) {
284 Key *private = id->key; 320 struct sshkey *private = id->key;
285 /* Decrypt the challenge using the private key. */ 321 /* Decrypt the challenge using the private key. */
286 if (rsa_private_decrypt(challenge, challenge, private->rsa) != 0) 322 if ((r = rsa_private_decrypt(challenge, challenge,
287 goto failure; 323 private->rsa) != 0)) {
324 fatal("%s: rsa_public_encrypt: %s", __func__,
325 ssh_err(r));
326 goto failure; /* XXX ? */
327 }
288 328
289 /* The response is MD5 of decrypted challenge plus session id. */ 329 /* The response is MD5 of decrypted challenge plus session id */
290 len = BN_num_bytes(challenge); 330 len = BN_num_bytes(challenge);
291 if (len <= 0 || len > 32) { 331 if (len <= 0 || len > 32) {
292 logit("process_authentication_challenge: bad challenge length %d", len); 332 logit("%s: bad challenge length %d", __func__, len);
293 goto failure; 333 goto failure;
294 } 334 }
295 memset(buf, 0, 32); 335 memset(buf, 0, 32);
@@ -302,21 +342,22 @@ process_authentication_challenge1(SocketEntry *e)
302 ssh_digest_free(md); 342 ssh_digest_free(md);
303 343
304 /* Send the response. */ 344 /* Send the response. */
305 buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE); 345 if ((r = sshbuf_put_u8(msg, SSH_AGENT_RSA_RESPONSE)) != 0 ||
306 for (i = 0; i < 16; i++) 346 (r = sshbuf_put(msg, mdbuf, sizeof(mdbuf))) != 0)
307 buffer_put_char(&msg, mdbuf[i]); 347 fatal("%s: buffer error: %s", __func__, ssh_err(r));
308 goto send; 348 goto send;
309 } 349 }
310 350
311failure: 351 failure:
312 /* Unknown identity or protocol error. Send failure. */ 352 /* Unknown identity or protocol error. Send failure. */
313 buffer_put_char(&msg, SSH_AGENT_FAILURE); 353 if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0)
314send: 354 fatal("%s: buffer error: %s", __func__, ssh_err(r));
315 buffer_put_int(&e->output, buffer_len(&msg)); 355 send:
316 buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); 356 if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
317 key_free(key); 357 fatal("%s: buffer error: %s", __func__, ssh_err(r));
358 sshkey_free(key);
318 BN_clear_free(challenge); 359 BN_clear_free(challenge);
319 buffer_free(&msg); 360 sshbuf_free(msg);
320} 361}
321#endif 362#endif
322 363
@@ -325,54 +366,56 @@ static void
325process_sign_request2(SocketEntry *e) 366process_sign_request2(SocketEntry *e)
326{ 367{
327 u_char *blob, *data, *signature = NULL; 368 u_char *blob, *data, *signature = NULL;
328 u_int blen, dlen, slen = 0; 369 size_t blen, dlen, slen = 0;
329 extern int datafellows; 370 u_int compat = 0, flags;
330 int odatafellows; 371 int r, ok = -1;
331 int ok = -1, flags; 372 struct sshbuf *msg;
332 Buffer msg; 373 struct sshkey *key;
333 Key *key; 374
334 375 if ((r = sshbuf_get_string(e->request, &blob, &blen)) != 0 ||
335 datafellows = 0; 376 (r = sshbuf_get_string(e->request, &data, &dlen)) != 0 ||
336 377 (r = sshbuf_get_u32(e->request, &flags)) != 0)
337 blob = buffer_get_string(&e->request, &blen); 378 fatal("%s: buffer error: %s", __func__, ssh_err(r));
338 data = buffer_get_string(&e->request, &dlen);
339
340 flags = buffer_get_int(&e->request);
341 odatafellows = datafellows;
342 if (flags & SSH_AGENT_OLD_SIGNATURE) 379 if (flags & SSH_AGENT_OLD_SIGNATURE)
343 datafellows = SSH_BUG_SIGBLOB; 380 compat = SSH_BUG_SIGBLOB;
344 381
345 key = key_from_blob(blob, blen); 382 if ((ok = sshkey_from_blob(blob, blen, &key)) != 0)
346 if (key != NULL) { 383 error("%s: cannot parse key blob: %s", __func__, ssh_err(ok));
384 else {
347 Identity *id = lookup_identity(key, 2); 385 Identity *id = lookup_identity(key, 2);
348 if (id != NULL && (!id->confirm || confirm_key(id) == 0)) 386 if (id != NULL && (!id->confirm || confirm_key(id) == 0)) {
349 ok = key_sign(id->key, &signature, &slen, data, dlen); 387 if ((ok = sshkey_sign(id->key, &signature, &slen,
350 key_free(key); 388 data, dlen, compat)) != 0)
389 error("%s: sshkey_sign: %s",
390 __func__, ssh_err(ok));
391 }
392 sshkey_free(key);
351 } 393 }
352 buffer_init(&msg); 394 if ((msg = sshbuf_new()) == NULL)
395 fatal("%s: sshbuf_new failed", __func__);
353 if (ok == 0) { 396 if (ok == 0) {
354 buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE); 397 if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 ||
355 buffer_put_string(&msg, signature, slen); 398 (r = sshbuf_put_string(msg, signature, slen)) != 0)
356 } else { 399 fatal("%s: buffer error: %s", __func__, ssh_err(r));
357 buffer_put_char(&msg, SSH_AGENT_FAILURE); 400 } else if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0)
358 } 401 fatal("%s: buffer error: %s", __func__, ssh_err(r));
359 buffer_put_int(&e->output, buffer_len(&msg)); 402
360 buffer_append(&e->output, buffer_ptr(&msg), 403 if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
361 buffer_len(&msg)); 404 fatal("%s: buffer error: %s", __func__, ssh_err(r));
362 buffer_free(&msg); 405
406 sshbuf_free(msg);
363 free(data); 407 free(data);
364 free(blob); 408 free(blob);
365 free(signature); 409 free(signature);
366 datafellows = odatafellows;
367} 410}
368 411
369/* shared */ 412/* shared */
370static void 413static void
371process_remove_identity(SocketEntry *e, int version) 414process_remove_identity(SocketEntry *e, int version)
372{ 415{
373 u_int blen; 416 size_t blen;
374 int success = 0; 417 int r, success = 0;
375 Key *key = NULL; 418 struct sshkey *key = NULL;
376 u_char *blob; 419 u_char *blob;
377#ifdef WITH_SSH1 420#ifdef WITH_SSH1
378 u_int bits; 421 u_int bits;
@@ -381,19 +424,27 @@ process_remove_identity(SocketEntry *e, int version)
381 switch (version) { 424 switch (version) {
382#ifdef WITH_SSH1 425#ifdef WITH_SSH1
383 case 1: 426 case 1:
384 key = key_new(KEY_RSA1); 427 if ((key = sshkey_new(KEY_RSA1)) == NULL) {
385 bits = buffer_get_int(&e->request); 428 error("%s: sshkey_new failed", __func__);
386 buffer_get_bignum(&e->request, key->rsa->e); 429 return;
387 buffer_get_bignum(&e->request, key->rsa->n); 430 }
388 431 if ((r = sshbuf_get_u32(e->request, &bits)) != 0 ||
389 if (bits != key_size(key)) 432 (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 ||
390 logit("Warning: identity keysize mismatch: actual %u, announced %u", 433 (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0)
391 key_size(key), bits); 434 fatal("%s: buffer error: %s", __func__, ssh_err(r));
435
436 if (bits != sshkey_size(key))
437 logit("Warning: identity keysize mismatch: "
438 "actual %u, announced %u",
439 sshkey_size(key), bits);
392 break; 440 break;
393#endif /* WITH_SSH1 */ 441#endif /* WITH_SSH1 */
394 case 2: 442 case 2:
395 blob = buffer_get_string(&e->request, &blen); 443 if ((r = sshbuf_get_string(e->request, &blob, &blen)) != 0)
396 key = key_from_blob(blob, blen); 444 fatal("%s: buffer error: %s", __func__, ssh_err(r));
445 if ((r = sshkey_from_blob(blob, blen, &key)) != 0)
446 error("%s: sshkey_from_blob failed: %s",
447 __func__, ssh_err(r));
397 free(blob); 448 free(blob);
398 break; 449 break;
399 } 450 }
@@ -417,11 +468,9 @@ process_remove_identity(SocketEntry *e, int version)
417 tab->nentries--; 468 tab->nentries--;
418 success = 1; 469 success = 1;
419 } 470 }
420 key_free(key); 471 sshkey_free(key);
421 } 472 }
422 buffer_put_int(&e->output, 1); 473 send_status(e, success);
423 buffer_put_char(&e->output,
424 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
425} 474}
426 475
427static void 476static void
@@ -441,8 +490,7 @@ process_remove_all_identities(SocketEntry *e, int version)
441 tab->nentries = 0; 490 tab->nentries = 0;
442 491
443 /* Send success. */ 492 /* Send success. */
444 buffer_put_int(&e->output, 1); 493 send_status(e, 1);
445 buffer_put_char(&e->output, SSH_AGENT_SUCCESS);
446} 494}
447 495
448/* removes expired keys and returns number of seconds until the next expiry */ 496/* removes expired keys and returns number of seconds until the next expiry */
@@ -476,71 +524,104 @@ reaper(void)
476 return (deadline - now); 524 return (deadline - now);
477} 525}
478 526
527/*
528 * XXX this and the corresponding serialisation function probably belongs
529 * in key.c
530 */
531static int
532agent_decode_rsa1(struct sshbuf *m, struct sshkey **kp)
533{
534 struct sshkey *k = NULL;
535 int r = SSH_ERR_INTERNAL_ERROR;
536
537 *kp = NULL;
538 if ((k = sshkey_new_private(KEY_RSA1)) == NULL)
539 return SSH_ERR_ALLOC_FAIL;
540
541 if ((r = sshbuf_get_u32(m, NULL)) != 0 || /* ignored */
542 (r = sshbuf_get_bignum1(m, k->rsa->n)) != 0 ||
543 (r = sshbuf_get_bignum1(m, k->rsa->e)) != 0 ||
544 (r = sshbuf_get_bignum1(m, k->rsa->d)) != 0 ||
545 (r = sshbuf_get_bignum1(m, k->rsa->iqmp)) != 0 ||
546 /* SSH1 and SSL have p and q swapped */
547 (r = sshbuf_get_bignum1(m, k->rsa->q)) != 0 || /* p */
548 (r = sshbuf_get_bignum1(m, k->rsa->p)) != 0) /* q */
549 goto out;
550
551 /* Generate additional parameters */
552 if ((r = rsa_generate_additional_parameters(k->rsa)) != 0)
553 goto out;
554 /* enable blinding */
555 if (RSA_blinding_on(k->rsa, NULL) != 1) {
556 r = SSH_ERR_LIBCRYPTO_ERROR;
557 goto out;
558 }
559
560 r = 0; /* success */
561 out:
562 if (r == 0)
563 *kp = k;
564 else
565 sshkey_free(k);
566 return r;
567}
568
479static void 569static void
480process_add_identity(SocketEntry *e, int version) 570process_add_identity(SocketEntry *e, int version)
481{ 571{
482 Idtab *tab = idtab_lookup(version); 572 Idtab *tab = idtab_lookup(version);
483 Identity *id; 573 Identity *id;
484 int type, success = 0, confirm = 0; 574 int success = 0, confirm = 0;
485 char *comment; 575 u_int seconds;
576 char *comment = NULL;
486 time_t death = 0; 577 time_t death = 0;
487 Key *k = NULL; 578 struct sshkey *k = NULL;
579 u_char ctype;
580 int r = SSH_ERR_INTERNAL_ERROR;
488 581
489 switch (version) { 582 switch (version) {
490#ifdef WITH_SSH1 583#ifdef WITH_SSH1
491 case 1: 584 case 1:
492 k = key_new_private(KEY_RSA1); 585 r = agent_decode_rsa1(e->request, &k);
493 (void) buffer_get_int(&e->request); /* ignored */
494 buffer_get_bignum(&e->request, k->rsa->n);
495 buffer_get_bignum(&e->request, k->rsa->e);
496 buffer_get_bignum(&e->request, k->rsa->d);
497 buffer_get_bignum(&e->request, k->rsa->iqmp);
498
499 /* SSH and SSL have p and q swapped */
500 buffer_get_bignum(&e->request, k->rsa->q); /* p */
501 buffer_get_bignum(&e->request, k->rsa->p); /* q */
502
503 /* Generate additional parameters */
504 if (rsa_generate_additional_parameters(k->rsa) != 0)
505 fatal("%s: rsa_generate_additional_parameters "
506 "error", __func__);
507
508 /* enable blinding */
509 if (RSA_blinding_on(k->rsa, NULL) != 1) {
510 error("process_add_identity: RSA_blinding_on failed");
511 key_free(k);
512 goto send;
513 }
514 break; 586 break;
515#endif /* WITH_SSH1 */ 587#endif /* WITH_SSH1 */
516 case 2: 588 case 2:
517 k = key_private_deserialize(&e->request); 589 r = sshkey_private_deserialize(e->request, &k);
518 if (k == NULL) {
519 buffer_clear(&e->request);
520 goto send;
521 }
522 break; 590 break;
523 } 591 }
524 if (k == NULL) 592 if (r != 0 || k == NULL ||
525 goto send; 593 (r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) {
526 comment = buffer_get_string(&e->request, NULL); 594 error("%s: decode private key: %s", __func__, ssh_err(r));
595 goto err;
596 }
527 597
528 while (buffer_len(&e->request)) { 598 while (sshbuf_len(e->request)) {
529 switch ((type = buffer_get_char(&e->request))) { 599 if ((r = sshbuf_get_u8(e->request, &ctype)) != 0) {
600 error("%s: buffer error: %s", __func__, ssh_err(r));
601 goto err;
602 }
603 switch (ctype) {
530 case SSH_AGENT_CONSTRAIN_LIFETIME: 604 case SSH_AGENT_CONSTRAIN_LIFETIME:
531 death = monotime() + buffer_get_int(&e->request); 605 if ((r = sshbuf_get_u32(e->request, &seconds)) != 0) {
606 error("%s: bad lifetime constraint: %s",
607 __func__, ssh_err(r));
608 goto err;
609 }
610 death = monotime() + seconds;
532 break; 611 break;
533 case SSH_AGENT_CONSTRAIN_CONFIRM: 612 case SSH_AGENT_CONSTRAIN_CONFIRM:
534 confirm = 1; 613 confirm = 1;
535 break; 614 break;
536 default: 615 default:
537 error("process_add_identity: " 616 error("%s: Unknown constraint %d", __func__, ctype);
538 "Unknown constraint type %d", type); 617 err:
618 sshbuf_reset(e->request);
539 free(comment); 619 free(comment);
540 key_free(k); 620 sshkey_free(k);
541 goto send; 621 goto send;
542 } 622 }
543 } 623 }
624
544 success = 1; 625 success = 1;
545 if (lifetime && !death) 626 if (lifetime && !death)
546 death = monotime() + lifetime; 627 death = monotime() + lifetime;
@@ -551,26 +632,25 @@ process_add_identity(SocketEntry *e, int version)
551 /* Increment the number of identities. */ 632 /* Increment the number of identities. */
552 tab->nentries++; 633 tab->nentries++;
553 } else { 634 } else {
554 key_free(k); 635 sshkey_free(k);
555 free(id->comment); 636 free(id->comment);
556 } 637 }
557 id->comment = comment; 638 id->comment = comment;
558 id->death = death; 639 id->death = death;
559 id->confirm = confirm; 640 id->confirm = confirm;
560send: 641send:
561 buffer_put_int(&e->output, 1); 642 send_status(e, success);
562 buffer_put_char(&e->output,
563 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
564} 643}
565 644
566/* XXX todo: encrypt sensitive data with passphrase */ 645/* XXX todo: encrypt sensitive data with passphrase */
567static void 646static void
568process_lock_agent(SocketEntry *e, int lock) 647process_lock_agent(SocketEntry *e, int lock)
569{ 648{
570 int success = 0; 649 int r, success = 0;
571 char *passwd; 650 char *passwd;
572 651
573 passwd = buffer_get_string(&e->request, NULL); 652 if ((r = sshbuf_get_cstring(e->request, &passwd, NULL)) != 0)
653 fatal("%s: buffer error: %s", __func__, ssh_err(r));
574 if (locked && !lock && strcmp(passwd, lock_passwd) == 0) { 654 if (locked && !lock && strcmp(passwd, lock_passwd) == 0) {
575 locked = 0; 655 locked = 0;
576 explicit_bzero(lock_passwd, strlen(lock_passwd)); 656 explicit_bzero(lock_passwd, strlen(lock_passwd));
@@ -584,25 +664,25 @@ process_lock_agent(SocketEntry *e, int lock)
584 } 664 }
585 explicit_bzero(passwd, strlen(passwd)); 665 explicit_bzero(passwd, strlen(passwd));
586 free(passwd); 666 free(passwd);
587 667 send_status(e, success);
588 buffer_put_int(&e->output, 1);
589 buffer_put_char(&e->output,
590 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
591} 668}
592 669
593static void 670static void
594no_identities(SocketEntry *e, u_int type) 671no_identities(SocketEntry *e, u_int type)
595{ 672{
596 Buffer msg; 673 struct sshbuf *msg;
674 int r;
597 675
598 buffer_init(&msg); 676 if ((msg = sshbuf_new()) == NULL)
599 buffer_put_char(&msg, 677 fatal("%s: sshbuf_new failed", __func__);
678 if ((r = sshbuf_put_u8(msg,
600 (type == SSH_AGENTC_REQUEST_RSA_IDENTITIES) ? 679 (type == SSH_AGENTC_REQUEST_RSA_IDENTITIES) ?
601 SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER); 680 SSH_AGENT_RSA_IDENTITIES_ANSWER :
602 buffer_put_int(&msg, 0); 681 SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
603 buffer_put_int(&e->output, buffer_len(&msg)); 682 (r = sshbuf_put_u32(msg, 0)) != 0 ||
604 buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); 683 (r = sshbuf_put_stringb(e->output, msg)) != 0)
605 buffer_free(&msg); 684 fatal("%s: buffer error: %s", __func__, ssh_err(r));
685 sshbuf_free(msg);
606} 686}
607 687
608#ifdef ENABLE_PKCS11 688#ifdef ENABLE_PKCS11
@@ -610,19 +690,27 @@ static void
610process_add_smartcard_key(SocketEntry *e) 690process_add_smartcard_key(SocketEntry *e)
611{ 691{
612 char *provider = NULL, *pin; 692 char *provider = NULL, *pin;
613 int i, type, version, count = 0, success = 0, confirm = 0; 693 int r, i, version, count = 0, success = 0, confirm = 0;
694 u_int seconds;
614 time_t death = 0; 695 time_t death = 0;
615 Key **keys = NULL, *k; 696 u_char type;
697 struct sshkey **keys = NULL, *k;
616 Identity *id; 698 Identity *id;
617 Idtab *tab; 699 Idtab *tab;
618 700
619 provider = buffer_get_string(&e->request, NULL); 701 if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 ||
620 pin = buffer_get_string(&e->request, NULL); 702 (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0)
703 fatal("%s: buffer error: %s", __func__, ssh_err(r));
621 704
622 while (buffer_len(&e->request)) { 705 while (sshbuf_len(e->request)) {
623 switch ((type = buffer_get_char(&e->request))) { 706 if ((r = sshbuf_get_u8(e->request, &type)) != 0)
707 fatal("%s: buffer error: %s", __func__, ssh_err(r));
708 switch (type) {
624 case SSH_AGENT_CONSTRAIN_LIFETIME: 709 case SSH_AGENT_CONSTRAIN_LIFETIME:
625 death = monotime() + buffer_get_int(&e->request); 710 if ((r = sshbuf_get_u32(e->request, &seconds)) != 0)
711 fatal("%s: buffer error: %s",
712 __func__, ssh_err(r));
713 death = monotime() + seconds;
626 break; 714 break;
627 case SSH_AGENT_CONSTRAIN_CONFIRM: 715 case SSH_AGENT_CONSTRAIN_CONFIRM:
628 confirm = 1; 716 confirm = 1;
@@ -652,7 +740,7 @@ process_add_smartcard_key(SocketEntry *e)
652 tab->nentries++; 740 tab->nentries++;
653 success = 1; 741 success = 1;
654 } else { 742 } else {
655 key_free(k); 743 sshkey_free(k);
656 } 744 }
657 keys[i] = NULL; 745 keys[i] = NULL;
658 } 746 }
@@ -660,21 +748,20 @@ send:
660 free(pin); 748 free(pin);
661 free(provider); 749 free(provider);
662 free(keys); 750 free(keys);
663 buffer_put_int(&e->output, 1); 751 send_status(e, success);
664 buffer_put_char(&e->output,
665 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
666} 752}
667 753
668static void 754static void
669process_remove_smartcard_key(SocketEntry *e) 755process_remove_smartcard_key(SocketEntry *e)
670{ 756{
671 char *provider = NULL, *pin = NULL; 757 char *provider = NULL, *pin = NULL;
672 int version, success = 0; 758 int r, version, success = 0;
673 Identity *id, *nxt; 759 Identity *id, *nxt;
674 Idtab *tab; 760 Idtab *tab;
675 761
676 provider = buffer_get_string(&e->request, NULL); 762 if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 ||
677 pin = buffer_get_string(&e->request, NULL); 763 (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0)
764 fatal("%s: buffer error: %s", __func__, ssh_err(r));
678 free(pin); 765 free(pin);
679 766
680 for (version = 1; version < 3; version++) { 767 for (version = 1; version < 3; version++) {
@@ -697,9 +784,7 @@ process_remove_smartcard_key(SocketEntry *e)
697 error("process_remove_smartcard_key:" 784 error("process_remove_smartcard_key:"
698 " pkcs11_del_provider failed"); 785 " pkcs11_del_provider failed");
699 free(provider); 786 free(provider);
700 buffer_put_int(&e->output, 1); 787 send_status(e, success);
701 buffer_put_char(&e->output,
702 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
703} 788}
704#endif /* ENABLE_PKCS11 */ 789#endif /* ENABLE_PKCS11 */
705 790
@@ -708,30 +793,31 @@ process_remove_smartcard_key(SocketEntry *e)
708static void 793static void
709process_message(SocketEntry *e) 794process_message(SocketEntry *e)
710{ 795{
711 u_int msg_len, type; 796 u_int msg_len;
712 u_char *cp; 797 u_char type;
798 const u_char *cp;
799 int r;
713 800
714 if (buffer_len(&e->input) < 5) 801 if (sshbuf_len(e->input) < 5)
715 return; /* Incomplete message. */ 802 return; /* Incomplete message. */
716 cp = buffer_ptr(&e->input); 803 cp = sshbuf_ptr(e->input);
717 msg_len = get_u32(cp); 804 msg_len = PEEK_U32(cp);
718 if (msg_len > 256 * 1024) { 805 if (msg_len > 256 * 1024) {
719 close_socket(e); 806 close_socket(e);
720 return; 807 return;
721 } 808 }
722 if (buffer_len(&e->input) < msg_len + 4) 809 if (sshbuf_len(e->input) < msg_len + 4)
723 return; 810 return;
724 811
725 /* move the current input to e->request */ 812 /* move the current input to e->request */
726 buffer_consume(&e->input, 4); 813 sshbuf_reset(e->request);
727 buffer_clear(&e->request); 814 if ((r = sshbuf_get_stringb(e->input, e->request)) != 0 ||
728 buffer_append(&e->request, buffer_ptr(&e->input), msg_len); 815 (r = sshbuf_get_u8(e->request, &type)) != 0)
729 buffer_consume(&e->input, msg_len); 816 fatal("%s: buffer error: %s", __func__, ssh_err(r));
730 type = buffer_get_char(&e->request);
731 817
732 /* check wheter agent is locked */ 818 /* check wheter agent is locked */
733 if (locked && type != SSH_AGENTC_UNLOCK) { 819 if (locked && type != SSH_AGENTC_UNLOCK) {
734 buffer_clear(&e->request); 820 sshbuf_reset(e->request);
735 switch (type) { 821 switch (type) {
736 case SSH_AGENTC_REQUEST_RSA_IDENTITIES: 822 case SSH_AGENTC_REQUEST_RSA_IDENTITIES:
737 case SSH2_AGENTC_REQUEST_IDENTITIES: 823 case SSH2_AGENTC_REQUEST_IDENTITIES:
@@ -740,8 +826,7 @@ process_message(SocketEntry *e)
740 break; 826 break;
741 default: 827 default:
742 /* send a fail message for all other request types */ 828 /* send a fail message for all other request types */
743 buffer_put_int(&e->output, 1); 829 send_status(e, 0);
744 buffer_put_char(&e->output, SSH_AGENT_FAILURE);
745 } 830 }
746 return; 831 return;
747 } 832 }
@@ -800,9 +885,8 @@ process_message(SocketEntry *e)
800 default: 885 default:
801 /* Unknown message. Respond with failure. */ 886 /* Unknown message. Respond with failure. */
802 error("Unknown message %d", type); 887 error("Unknown message %d", type);
803 buffer_clear(&e->request); 888 sshbuf_reset(e->request);
804 buffer_put_int(&e->output, 1); 889 send_status(e, 0);
805 buffer_put_char(&e->output, SSH_AGENT_FAILURE);
806 break; 890 break;
807 } 891 }
808} 892}
@@ -820,9 +904,12 @@ new_socket(sock_type type, int fd)
820 for (i = 0; i < sockets_alloc; i++) 904 for (i = 0; i < sockets_alloc; i++)
821 if (sockets[i].type == AUTH_UNUSED) { 905 if (sockets[i].type == AUTH_UNUSED) {
822 sockets[i].fd = fd; 906 sockets[i].fd = fd;
823 buffer_init(&sockets[i].input); 907 if ((sockets[i].input = sshbuf_new()) == NULL)
824 buffer_init(&sockets[i].output); 908 fatal("%s: sshbuf_new failed", __func__);
825 buffer_init(&sockets[i].request); 909 if ((sockets[i].output = sshbuf_new()) == NULL)
910 fatal("%s: sshbuf_new failed", __func__);
911 if ((sockets[i].request = sshbuf_new()) == NULL)
912 fatal("%s: sshbuf_new failed", __func__);
826 sockets[i].type = type; 913 sockets[i].type = type;
827 return; 914 return;
828 } 915 }
@@ -833,9 +920,12 @@ new_socket(sock_type type, int fd)
833 sockets[i].type = AUTH_UNUSED; 920 sockets[i].type = AUTH_UNUSED;
834 sockets_alloc = new_alloc; 921 sockets_alloc = new_alloc;
835 sockets[old_alloc].fd = fd; 922 sockets[old_alloc].fd = fd;
836 buffer_init(&sockets[old_alloc].input); 923 if ((sockets[old_alloc].input = sshbuf_new()) == NULL)
837 buffer_init(&sockets[old_alloc].output); 924 fatal("%s: sshbuf_new failed", __func__);
838 buffer_init(&sockets[old_alloc].request); 925 if ((sockets[old_alloc].output = sshbuf_new()) == NULL)
926 fatal("%s: sshbuf_new failed", __func__);
927 if ((sockets[old_alloc].request = sshbuf_new()) == NULL)
928 fatal("%s: sshbuf_new failed", __func__);
839 sockets[old_alloc].type = type; 929 sockets[old_alloc].type = type;
840} 930}
841 931
@@ -881,7 +971,7 @@ prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp,
881 case AUTH_SOCKET: 971 case AUTH_SOCKET:
882 case AUTH_CONNECTION: 972 case AUTH_CONNECTION:
883 FD_SET(sockets[i].fd, *fdrp); 973 FD_SET(sockets[i].fd, *fdrp);
884 if (buffer_len(&sockets[i].output) > 0) 974 if (sshbuf_len(sockets[i].output) > 0)
885 FD_SET(sockets[i].fd, *fdwp); 975 FD_SET(sockets[i].fd, *fdwp);
886 break; 976 break;
887 default: 977 default:
@@ -908,7 +998,7 @@ after_select(fd_set *readset, fd_set *writeset)
908 struct sockaddr_un sunaddr; 998 struct sockaddr_un sunaddr;
909 socklen_t slen; 999 socklen_t slen;
910 char buf[1024]; 1000 char buf[1024];
911 int len, sock; 1001 int len, sock, r;
912 u_int i, orig_alloc; 1002 u_int i, orig_alloc;
913 uid_t euid; 1003 uid_t euid;
914 gid_t egid; 1004 gid_t egid;
@@ -944,11 +1034,11 @@ after_select(fd_set *readset, fd_set *writeset)
944 } 1034 }
945 break; 1035 break;
946 case AUTH_CONNECTION: 1036 case AUTH_CONNECTION:
947 if (buffer_len(&sockets[i].output) > 0 && 1037 if (sshbuf_len(sockets[i].output) > 0 &&
948 FD_ISSET(sockets[i].fd, writeset)) { 1038 FD_ISSET(sockets[i].fd, writeset)) {
949 len = write(sockets[i].fd, 1039 len = write(sockets[i].fd,
950 buffer_ptr(&sockets[i].output), 1040 sshbuf_ptr(sockets[i].output),
951 buffer_len(&sockets[i].output)); 1041 sshbuf_len(sockets[i].output));
952 if (len == -1 && (errno == EAGAIN || 1042 if (len == -1 && (errno == EAGAIN ||
953 errno == EWOULDBLOCK || 1043 errno == EWOULDBLOCK ||
954 errno == EINTR)) 1044 errno == EINTR))
@@ -957,7 +1047,10 @@ after_select(fd_set *readset, fd_set *writeset)
957 close_socket(&sockets[i]); 1047 close_socket(&sockets[i]);
958 break; 1048 break;
959 } 1049 }
960 buffer_consume(&sockets[i].output, len); 1050 if ((r = sshbuf_consume(sockets[i].output,
1051 len)) != 0)
1052 fatal("%s: buffer error: %s",
1053 __func__, ssh_err(r));
961 } 1054 }
962 if (FD_ISSET(sockets[i].fd, readset)) { 1055 if (FD_ISSET(sockets[i].fd, readset)) {
963 len = read(sockets[i].fd, buf, sizeof(buf)); 1056 len = read(sockets[i].fd, buf, sizeof(buf));
@@ -969,7 +1062,10 @@ after_select(fd_set *readset, fd_set *writeset)
969 close_socket(&sockets[i]); 1062 close_socket(&sockets[i]);
970 break; 1063 break;
971 } 1064 }
972 buffer_append(&sockets[i].input, buf, len); 1065 if ((r = sshbuf_put(sockets[i].input,
1066 buf, len)) != 0)
1067 fatal("%s: buffer error: %s",
1068 __func__, ssh_err(r));
973 explicit_bzero(buf, sizeof(buf)); 1069 explicit_bzero(buf, sizeof(buf));
974 process_message(&sockets[i]); 1070 process_message(&sockets[i]);
975 } 1071 }