- markus@cvs.openbsd.org 2001/06/26 20:14:11
[key.c key.h ssh.c sshconnect1.c sshconnect2.c] add smartcard support to the client, too (now you can use both the agent and the client).
This commit is contained in:
parent
eb7a84c49e
commit
c5b680018b
3
key.c
3
key.c
|
@ -32,7 +32,7 @@
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: key.c,v 1.28 2001/06/25 08:25:37 markus Exp $");
|
RCSID("$OpenBSD: key.c,v 1.29 2001/06/26 20:14:10 markus Exp $");
|
||||||
|
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ key_new(int type)
|
||||||
DSA *dsa;
|
DSA *dsa;
|
||||||
k = xmalloc(sizeof(*k));
|
k = xmalloc(sizeof(*k));
|
||||||
k->type = type;
|
k->type = type;
|
||||||
|
k->flags = 0;
|
||||||
k->dsa = NULL;
|
k->dsa = NULL;
|
||||||
k->rsa = NULL;
|
k->rsa = NULL;
|
||||||
switch (k->type) {
|
switch (k->type) {
|
||||||
|
|
9
key.h
9
key.h
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: key.h,v 1.15 2001/06/26 17:27:23 markus Exp $ */
|
/* $OpenBSD: key.h,v 1.16 2001/06/26 20:14:10 markus Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||||
|
@ -44,8 +44,13 @@ enum fp_rep {
|
||||||
SSH_FP_HEX,
|
SSH_FP_HEX,
|
||||||
SSH_FP_BUBBLEBABBLE
|
SSH_FP_BUBBLEBABBLE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* key is stored in external hardware */
|
||||||
|
#define KEY_FLAG_EXT 0x0001
|
||||||
|
|
||||||
struct Key {
|
struct Key {
|
||||||
int type;
|
int type;
|
||||||
|
int flags;
|
||||||
RSA *rsa;
|
RSA *rsa;
|
||||||
DSA *dsa;
|
DSA *dsa;
|
||||||
};
|
};
|
||||||
|
|
49
ssh.c
49
ssh.c
|
@ -39,7 +39,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: ssh.c,v 1.126 2001/06/23 15:12:21 itojun Exp $");
|
RCSID("$OpenBSD: ssh.c,v 1.127 2001/06/26 20:14:11 markus Exp $");
|
||||||
|
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
|
@ -69,6 +69,11 @@ RCSID("$OpenBSD: ssh.c,v 1.126 2001/06/23 15:12:21 itojun Exp $");
|
||||||
#include "mac.h"
|
#include "mac.h"
|
||||||
#include "sshtty.h"
|
#include "sshtty.h"
|
||||||
|
|
||||||
|
#ifdef SMARTCARD
|
||||||
|
#include <openssl/engine.h>
|
||||||
|
#include "scard.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE___PROGNAME
|
#ifdef HAVE___PROGNAME
|
||||||
extern char *__progname;
|
extern char *__progname;
|
||||||
#else
|
#else
|
||||||
|
@ -146,6 +151,11 @@ Buffer command;
|
||||||
/* Should we execute a command or invoke a subsystem? */
|
/* Should we execute a command or invoke a subsystem? */
|
||||||
int subsystem_flag = 0;
|
int subsystem_flag = 0;
|
||||||
|
|
||||||
|
#ifdef SMARTCARD
|
||||||
|
/* Smartcard reader id */
|
||||||
|
int sc_reader_num = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Prints a help message to the user. This function never returns. */
|
/* Prints a help message to the user. This function never returns. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -320,7 +330,7 @@ main(int ac, char **av)
|
||||||
opt = av[optind][1];
|
opt = av[optind][1];
|
||||||
if (!opt)
|
if (!opt)
|
||||||
usage();
|
usage();
|
||||||
if (strchr("eilcmpbLRDo", opt)) { /* options with arguments */
|
if (strchr("eilcmpbILRDo", opt)) { /* options with arguments */
|
||||||
optarg = av[optind] + 2;
|
optarg = av[optind] + 2;
|
||||||
if (strcmp(optarg, "") == 0) {
|
if (strcmp(optarg, "") == 0) {
|
||||||
if (optind >= ac - 1)
|
if (optind >= ac - 1)
|
||||||
|
@ -387,6 +397,13 @@ main(int ac, char **av)
|
||||||
SSH_MAX_IDENTITY_FILES);
|
SSH_MAX_IDENTITY_FILES);
|
||||||
options.identity_files[options.num_identity_files++] = xstrdup(optarg);
|
options.identity_files[options.num_identity_files++] = xstrdup(optarg);
|
||||||
break;
|
break;
|
||||||
|
case 'I':
|
||||||
|
#ifdef SMARTCARD
|
||||||
|
sc_reader_num = atoi(optarg);
|
||||||
|
#else
|
||||||
|
fprintf(stderr, "no support for smartcards.\n");
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
if (tty_flag)
|
if (tty_flag)
|
||||||
force_tty_flag = 1;
|
force_tty_flag = 1;
|
||||||
|
@ -1140,4 +1157,32 @@ load_public_identity_files(void)
|
||||||
options.identity_files[i] = filename;
|
options.identity_files[i] = filename;
|
||||||
options.identity_keys[i] = public;
|
options.identity_keys[i] = public;
|
||||||
}
|
}
|
||||||
|
#ifdef SMARTCARD
|
||||||
|
if (sc_reader_num != -1 &&
|
||||||
|
options.num_identity_files + 1 < SSH_MAX_IDENTITY_FILES &&
|
||||||
|
(public = sc_get_key(sc_reader_num)) != NULL ) {
|
||||||
|
Key *new;
|
||||||
|
|
||||||
|
/* XXX ssh1 vs ssh2 */
|
||||||
|
new = key_new(KEY_RSA);
|
||||||
|
new->flags = KEY_FLAG_EXT;
|
||||||
|
BN_copy(new->rsa->n, public->rsa->n);
|
||||||
|
BN_copy(new->rsa->e, public->rsa->e);
|
||||||
|
RSA_set_method(new->rsa, sc_get_engine());
|
||||||
|
i = options.num_identity_files++;
|
||||||
|
options.identity_keys[i] = new;
|
||||||
|
options.identity_files[i] = xstrdup("smartcard rsa key");;
|
||||||
|
|
||||||
|
new = key_new(KEY_RSA1);
|
||||||
|
new->flags = KEY_FLAG_EXT;
|
||||||
|
BN_copy(new->rsa->n, public->rsa->n);
|
||||||
|
BN_copy(new->rsa->e, public->rsa->e);
|
||||||
|
RSA_set_method(new->rsa, sc_get_engine());
|
||||||
|
i = options.num_identity_files++;
|
||||||
|
options.identity_keys[i] = new;
|
||||||
|
options.identity_files[i] = xstrdup("smartcard rsa1 key");;
|
||||||
|
|
||||||
|
key_free(public);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: sshconnect1.c,v 1.37 2001/06/26 16:15:24 dugsong Exp $");
|
RCSID("$OpenBSD: sshconnect1.c,v 1.38 2001/06/26 20:14:11 markus Exp $");
|
||||||
|
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
@ -205,20 +205,17 @@ respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
|
||||||
* the user using it.
|
* the user using it.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
try_rsa_authentication(const char *authfile)
|
try_rsa_authentication(int idx)
|
||||||
{
|
{
|
||||||
BIGNUM *challenge;
|
BIGNUM *challenge;
|
||||||
Key *public, *private;
|
Key *public, *private;
|
||||||
char buf[300], *passphrase, *comment;
|
char buf[300], *passphrase, *comment, *authfile;
|
||||||
int i, type, quit, plen, clen;
|
int i, type, quit, plen, clen;
|
||||||
|
|
||||||
/* Try to load identification for the authentication key. */
|
public = options.identity_keys[idx];
|
||||||
/* XXKEYLOAD */
|
authfile = options.identity_files[idx];
|
||||||
public = key_load_public_type(KEY_RSA1, authfile, &comment);
|
comment = xstrdup(authfile);
|
||||||
if (public == NULL) {
|
|
||||||
/* Could not load it. Fail. */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
debug("Trying RSA authentication with key '%.100s'", comment);
|
debug("Trying RSA authentication with key '%.100s'", comment);
|
||||||
|
|
||||||
/* Tell the server that we are willing to authenticate using this key. */
|
/* Tell the server that we are willing to authenticate using this key. */
|
||||||
|
@ -227,9 +224,6 @@ try_rsa_authentication(const char *authfile)
|
||||||
packet_send();
|
packet_send();
|
||||||
packet_write_wait();
|
packet_write_wait();
|
||||||
|
|
||||||
/* We no longer need the public key. */
|
|
||||||
key_free(public);
|
|
||||||
|
|
||||||
/* Wait for server's response. */
|
/* Wait for server's response. */
|
||||||
type = packet_read(&plen);
|
type = packet_read(&plen);
|
||||||
|
|
||||||
|
@ -255,10 +249,14 @@ try_rsa_authentication(const char *authfile)
|
||||||
debug("Received RSA challenge from server.");
|
debug("Received RSA challenge from server.");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load the private key. Try first with empty passphrase; if it
|
* If the key is not stored in external hardware, we have to
|
||||||
|
* load the private key. Try first with empty passphrase; if it
|
||||||
* fails, ask for a passphrase.
|
* fails, ask for a passphrase.
|
||||||
*/
|
*/
|
||||||
private = key_load_private_type(KEY_RSA1, authfile, "", NULL);
|
if (public->flags && KEY_FLAG_EXT)
|
||||||
|
private = public;
|
||||||
|
else
|
||||||
|
private = key_load_private_type(KEY_RSA1, authfile, "", NULL);
|
||||||
if (private == NULL && !options.batch_mode) {
|
if (private == NULL && !options.batch_mode) {
|
||||||
snprintf(buf, sizeof(buf),
|
snprintf(buf, sizeof(buf),
|
||||||
"Enter passphrase for RSA key '%.100s': ", comment);
|
"Enter passphrase for RSA key '%.100s': ", comment);
|
||||||
|
@ -302,8 +300,9 @@ try_rsa_authentication(const char *authfile)
|
||||||
/* Compute and send a response to the challenge. */
|
/* Compute and send a response to the challenge. */
|
||||||
respond_to_rsa_challenge(challenge, private->rsa);
|
respond_to_rsa_challenge(challenge, private->rsa);
|
||||||
|
|
||||||
/* Destroy the private key. */
|
/* Destroy the private key unless it in external hardware. */
|
||||||
key_free(private);
|
if (!(private->flags & KEY_FLAG_EXT))
|
||||||
|
key_free(private);
|
||||||
|
|
||||||
/* We no longer need the challenge. */
|
/* We no longer need the challenge. */
|
||||||
BN_clear_free(challenge);
|
BN_clear_free(challenge);
|
||||||
|
@ -1218,7 +1217,7 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
|
||||||
for (i = 0; i < options.num_identity_files; i++)
|
for (i = 0; i < options.num_identity_files; i++)
|
||||||
if (options.identity_keys[i] != NULL &&
|
if (options.identity_keys[i] != NULL &&
|
||||||
options.identity_keys[i]->type == KEY_RSA1 &&
|
options.identity_keys[i]->type == KEY_RSA1 &&
|
||||||
try_rsa_authentication(options.identity_files[i]))
|
try_rsa_authentication(i))
|
||||||
goto success;
|
goto success;
|
||||||
}
|
}
|
||||||
/* Try challenge response authentication if the server supports it. */
|
/* Try challenge response authentication if the server supports it. */
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: sshconnect2.c,v 1.79 2001/06/25 20:26:37 stevesk Exp $");
|
RCSID("$OpenBSD: sshconnect2.c,v 1.80 2001/06/26 20:14:11 markus Exp $");
|
||||||
|
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#include <openssl/md5.h>
|
#include <openssl/md5.h>
|
||||||
|
@ -640,6 +640,11 @@ identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
|
||||||
idx = authctxt->last_key_hint;
|
idx = authctxt->last_key_hint;
|
||||||
if (idx < 0)
|
if (idx < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* private key is stored in external hardware */
|
||||||
|
if (options.identity_keys[idx]->flags & KEY_FLAG_EXT)
|
||||||
|
return key_sign(options.identity_keys[idx], sigp, lenp, data, datalen);
|
||||||
|
|
||||||
private = load_identity_file(options.identity_files[idx]);
|
private = load_identity_file(options.identity_files[idx]);
|
||||||
if (private == NULL)
|
if (private == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Reference in New Issue