summaryrefslogtreecommitdiff
path: root/authfd.c
diff options
context:
space:
mode:
Diffstat (limited to 'authfd.c')
-rw-r--r--authfd.c174
1 files changed, 18 insertions, 156 deletions
diff --git a/authfd.c b/authfd.c
index a634bcb81..a460fa350 100644
--- a/authfd.c
+++ b/authfd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfd.c,v 1.100 2015/12/04 16:41:28 markus Exp $ */ 1/* $OpenBSD: authfd.c,v 1.105 2017/07/01 13:50:45 djm 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
@@ -51,7 +51,6 @@
51 51
52#include "xmalloc.h" 52#include "xmalloc.h"
53#include "ssh.h" 53#include "ssh.h"
54#include "rsa.h"
55#include "sshbuf.h" 54#include "sshbuf.h"
56#include "sshkey.h" 55#include "sshkey.h"
57#include "authfd.h" 56#include "authfd.h"
@@ -199,43 +198,6 @@ ssh_lock_agent(int sock, int lock, const char *password)
199 return r; 198 return r;
200} 199}
201 200
202#ifdef WITH_SSH1
203static int
204deserialise_identity1(struct sshbuf *ids, struct sshkey **keyp, char **commentp)
205{
206 struct sshkey *key;
207 int r, keybits;
208 u_int32_t bits;
209 char *comment = NULL;
210
211 if ((key = sshkey_new(KEY_RSA1)) == NULL)
212 return SSH_ERR_ALLOC_FAIL;
213 if ((r = sshbuf_get_u32(ids, &bits)) != 0 ||
214 (r = sshbuf_get_bignum1(ids, key->rsa->e)) != 0 ||
215 (r = sshbuf_get_bignum1(ids, key->rsa->n)) != 0 ||
216 (r = sshbuf_get_cstring(ids, &comment, NULL)) != 0)
217 goto out;
218 keybits = BN_num_bits(key->rsa->n);
219 /* XXX previously we just warned here. I think we should be strict */
220 if (keybits < 0 || bits != (u_int)keybits) {
221 r = SSH_ERR_KEY_BITS_MISMATCH;
222 goto out;
223 }
224 if (keyp != NULL) {
225 *keyp = key;
226 key = NULL;
227 }
228 if (commentp != NULL) {
229 *commentp = comment;
230 comment = NULL;
231 }
232 r = 0;
233 out:
234 sshkey_free(key);
235 free(comment);
236 return r;
237}
238#endif
239 201
240static int 202static int
241deserialise_identity2(struct sshbuf *ids, struct sshkey **keyp, char **commentp) 203deserialise_identity2(struct sshbuf *ids, struct sshkey **keyp, char **commentp)
@@ -264,35 +226,21 @@ deserialise_identity2(struct sshbuf *ids, struct sshkey **keyp, char **commentp)
264 * Fetch list of identities held by the agent. 226 * Fetch list of identities held by the agent.
265 */ 227 */
266int 228int
267ssh_fetch_identitylist(int sock, int version, struct ssh_identitylist **idlp) 229ssh_fetch_identitylist(int sock, struct ssh_identitylist **idlp)
268{ 230{
269 u_char type, code1 = 0, code2 = 0; 231 u_char type;
270 u_int32_t num, i; 232 u_int32_t num, i;
271 struct sshbuf *msg; 233 struct sshbuf *msg;
272 struct ssh_identitylist *idl = NULL; 234 struct ssh_identitylist *idl = NULL;
273 int r; 235 int r;
274 236
275 /* Determine request and expected response types */
276 switch (version) {
277 case 1:
278 code1 = SSH_AGENTC_REQUEST_RSA_IDENTITIES;
279 code2 = SSH_AGENT_RSA_IDENTITIES_ANSWER;
280 break;
281 case 2:
282 code1 = SSH2_AGENTC_REQUEST_IDENTITIES;
283 code2 = SSH2_AGENT_IDENTITIES_ANSWER;
284 break;
285 default:
286 return SSH_ERR_INVALID_ARGUMENT;
287 }
288
289 /* 237 /*
290 * Send a message to the agent requesting for a list of the 238 * Send a message to the agent requesting for a list of the
291 * identities it can represent. 239 * identities it can represent.
292 */ 240 */
293 if ((msg = sshbuf_new()) == NULL) 241 if ((msg = sshbuf_new()) == NULL)
294 return SSH_ERR_ALLOC_FAIL; 242 return SSH_ERR_ALLOC_FAIL;
295 if ((r = sshbuf_put_u8(msg, code1)) != 0) 243 if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_REQUEST_IDENTITIES)) != 0)
296 goto out; 244 goto out;
297 245
298 if ((r = ssh_request_reply(sock, msg, msg)) != 0) 246 if ((r = ssh_request_reply(sock, msg, msg)) != 0)
@@ -304,7 +252,7 @@ ssh_fetch_identitylist(int sock, int version, struct ssh_identitylist **idlp)
304 if (agent_failed(type)) { 252 if (agent_failed(type)) {
305 r = SSH_ERR_AGENT_FAILURE; 253 r = SSH_ERR_AGENT_FAILURE;
306 goto out; 254 goto out;
307 } else if (type != code2) { 255 } else if (type != SSH2_AGENT_IDENTITIES_ANSWER) {
308 r = SSH_ERR_INVALID_FORMAT; 256 r = SSH_ERR_INVALID_FORMAT;
309 goto out; 257 goto out;
310 } 258 }
@@ -329,25 +277,14 @@ ssh_fetch_identitylist(int sock, int version, struct ssh_identitylist **idlp)
329 goto out; 277 goto out;
330 } 278 }
331 for (i = 0; i < num;) { 279 for (i = 0; i < num;) {
332 switch (version) { 280 if ((r = deserialise_identity2(msg, &(idl->keys[i]),
333 case 1: 281 &(idl->comments[i]))) != 0) {
334#ifdef WITH_SSH1 282 if (r == SSH_ERR_KEY_TYPE_UNKNOWN) {
335 if ((r = deserialise_identity1(msg, 283 /* Gracefully skip unknown key types */
336 &(idl->keys[i]), &(idl->comments[i]))) != 0) 284 num--;
285 continue;
286 } else
337 goto out; 287 goto out;
338#endif
339 break;
340 case 2:
341 if ((r = deserialise_identity2(msg,
342 &(idl->keys[i]), &(idl->comments[i]))) != 0) {
343 if (r == SSH_ERR_KEY_TYPE_UNKNOWN) {
344 /* Gracefully skip unknown key types */
345 num--;
346 continue;
347 } else
348 goto out;
349 }
350 break;
351 } 288 }
352 i++; 289 i++;
353 } 290 }
@@ -385,50 +322,10 @@ ssh_free_identitylist(struct ssh_identitylist *idl)
385 * otherwise. 322 * otherwise.
386 */ 323 */
387 324
388#ifdef WITH_SSH1
389int
390ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge,
391 u_char session_id[16], u_char response[16])
392{
393 struct sshbuf *msg;
394 int r;
395 u_char type;
396
397 if (key->type != KEY_RSA1)
398 return SSH_ERR_INVALID_ARGUMENT;
399 if ((msg = sshbuf_new()) == NULL)
400 return SSH_ERR_ALLOC_FAIL;
401 if ((r = sshbuf_put_u8(msg, SSH_AGENTC_RSA_CHALLENGE)) != 0 ||
402 (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 ||
403 (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 ||
404 (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0 ||
405 (r = sshbuf_put_bignum1(msg, challenge)) != 0 ||
406 (r = sshbuf_put(msg, session_id, 16)) != 0 ||
407 (r = sshbuf_put_u32(msg, 1)) != 0) /* Response type for proto 1.1 */
408 goto out;
409 if ((r = ssh_request_reply(sock, msg, msg)) != 0)
410 goto out;
411 if ((r = sshbuf_get_u8(msg, &type)) != 0)
412 goto out;
413 if (agent_failed(type)) {
414 r = SSH_ERR_AGENT_FAILURE;
415 goto out;
416 } else if (type != SSH_AGENT_RSA_RESPONSE) {
417 r = SSH_ERR_INVALID_FORMAT;
418 goto out;
419 }
420 if ((r = sshbuf_get(msg, response, 16)) != 0)
421 goto out;
422 r = 0;
423 out:
424 sshbuf_free(msg);
425 return r;
426}
427#endif
428 325
429/* encode signature algoritm in flag bits, so we can keep the msg format */ 326/* encode signature algoritm in flag bits, so we can keep the msg format */
430static u_int 327static u_int
431agent_encode_alg(struct sshkey *key, const char *alg) 328agent_encode_alg(const struct sshkey *key, const char *alg)
432{ 329{
433 if (alg != NULL && key->type == KEY_RSA) { 330 if (alg != NULL && key->type == KEY_RSA) {
434 if (strcmp(alg, "rsa-sha2-256") == 0) 331 if (strcmp(alg, "rsa-sha2-256") == 0)
@@ -441,7 +338,7 @@ agent_encode_alg(struct sshkey *key, const char *alg)
441 338
442/* ask agent to sign data, returns err.h code on error, 0 on success */ 339/* ask agent to sign data, returns err.h code on error, 0 on success */
443int 340int
444ssh_agent_sign(int sock, struct sshkey *key, 341ssh_agent_sign(int sock, const struct sshkey *key,
445 u_char **sigp, size_t *lenp, 342 u_char **sigp, size_t *lenp,
446 const u_char *data, size_t datalen, const char *alg, u_int compat) 343 const u_char *data, size_t datalen, const char *alg, u_int compat)
447{ 344{
@@ -494,25 +391,6 @@ ssh_agent_sign(int sock, struct sshkey *key,
494 391
495/* Encode key for a message to the agent. */ 392/* Encode key for a message to the agent. */
496 393
497#ifdef WITH_SSH1
498static int
499ssh_encode_identity_rsa1(struct sshbuf *b, RSA *key, const char *comment)
500{
501 int r;
502
503 /* To keep within the protocol: p < q for ssh. in SSL p > q */
504 if ((r = sshbuf_put_u32(b, BN_num_bits(key->n))) != 0 ||
505 (r = sshbuf_put_bignum1(b, key->n)) != 0 ||
506 (r = sshbuf_put_bignum1(b, key->e)) != 0 ||
507 (r = sshbuf_put_bignum1(b, key->d)) != 0 ||
508 (r = sshbuf_put_bignum1(b, key->iqmp)) != 0 ||
509 (r = sshbuf_put_bignum1(b, key->q)) != 0 ||
510 (r = sshbuf_put_bignum1(b, key->p)) != 0 ||
511 (r = sshbuf_put_cstring(b, comment)) != 0)
512 return r;
513 return 0;
514}
515#endif
516 394
517static int 395static int
518ssh_encode_identity_ssh2(struct sshbuf *b, struct sshkey *key, 396ssh_encode_identity_ssh2(struct sshbuf *b, struct sshkey *key,
@@ -561,16 +439,6 @@ ssh_add_identity_constrained(int sock, struct sshkey *key, const char *comment,
561 return SSH_ERR_ALLOC_FAIL; 439 return SSH_ERR_ALLOC_FAIL;
562 440
563 switch (key->type) { 441 switch (key->type) {
564#ifdef WITH_SSH1
565 case KEY_RSA1:
566 type = constrained ?
567 SSH_AGENTC_ADD_RSA_ID_CONSTRAINED :
568 SSH_AGENTC_ADD_RSA_IDENTITY;
569 if ((r = sshbuf_put_u8(msg, type)) != 0 ||
570 (r = ssh_encode_identity_rsa1(msg, key->rsa, comment)) != 0)
571 goto out;
572 break;
573#endif
574#ifdef WITH_OPENSSL 442#ifdef WITH_OPENSSL
575 case KEY_RSA: 443 case KEY_RSA:
576 case KEY_RSA_CERT: 444 case KEY_RSA_CERT:
@@ -620,16 +488,6 @@ ssh_remove_identity(int sock, struct sshkey *key)
620 if ((msg = sshbuf_new()) == NULL) 488 if ((msg = sshbuf_new()) == NULL)
621 return SSH_ERR_ALLOC_FAIL; 489 return SSH_ERR_ALLOC_FAIL;
622 490
623#ifdef WITH_SSH1
624 if (key->type == KEY_RSA1) {
625 if ((r = sshbuf_put_u8(msg,
626 SSH_AGENTC_REMOVE_RSA_IDENTITY)) != 0 ||
627 (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 ||
628 (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 ||
629 (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0)
630 goto out;
631 } else
632#endif
633 if (key->type != KEY_UNSPEC) { 491 if (key->type != KEY_UNSPEC) {
634 if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) 492 if ((r = sshkey_to_blob(key, &blob, &blen)) != 0)
635 goto out; 493 goto out;
@@ -696,6 +554,10 @@ ssh_update_card(int sock, int add, const char *reader_id, const char *pin,
696/* 554/*
697 * Removes all identities from the agent. 555 * Removes all identities from the agent.
698 * This call is intended only for use by ssh-add(1) and like applications. 556 * This call is intended only for use by ssh-add(1) and like applications.
557 *
558 * This supports the SSH protocol 1 message to because, when clearing all
559 * keys from an agent, we generally want to clear both protocol v1 and v2
560 * keys.
699 */ 561 */
700int 562int
701ssh_remove_all_identities(int sock, int version) 563ssh_remove_all_identities(int sock, int version)