summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Rees <rees@cvs.openbsd.org>2002-03-21 21:54:35 +0000
committerJim Rees <rees@cvs.openbsd.org>2002-03-21 21:54:35 +0000
commit1e6c115eddb5e1954bd09d83a9a50c20390be545 (patch)
tree7ef8b29970258c1c6988b22225f8010639bd658e
parent74d71a21f81699632a7d334453274a14937cad55 (diff)
Add PIN-protection for secret key.
-rw-r--r--usr.bin/ssh/scard.c84
-rw-r--r--usr.bin/ssh/scard.h4
-rw-r--r--usr.bin/ssh/ssh-keygen.c4
3 files changed, 61 insertions, 31 deletions
diff --git a/usr.bin/ssh/scard.c b/usr.bin/ssh/scard.c
index 28e95a81d6a..134fd48e21f 100644
--- a/usr.bin/ssh/scard.c
+++ b/usr.bin/ssh/scard.c
@@ -24,7 +24,7 @@
#ifdef SMARTCARD
#include "includes.h"
-RCSID("$OpenBSD: scard.c,v 1.21 2002/03/21 18:08:15 rees Exp $");
+RCSID("$OpenBSD: scard.c,v 1.22 2002/03/21 21:54:34 rees Exp $");
#include <openssl/engine.h>
#include <openssl/evp.h>
@@ -33,8 +33,8 @@ RCSID("$OpenBSD: scard.c,v 1.21 2002/03/21 18:08:15 rees Exp $");
#include "key.h"
#include "log.h"
#include "xmalloc.h"
-#include "scard.h"
#include "readpass.h"
+#include "scard.h"
#ifdef OPENSSL_VERSION_NUMBER
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
@@ -53,10 +53,16 @@ RCSID("$OpenBSD: scard.c,v 1.21 2002/03/21 18:08:15 rees Exp $");
#define MAX_BUF_SIZE 256
+u_char DEFAUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63};
+
static int sc_fd = -1;
static char *sc_reader_id = NULL;
+static char *sc_pin = NULL;
static int cla = 0x00; /* class */
+static void sc_mk_digest(const char *pin, u_char *digest);
+static int get_AUT0(u_char *aut0);
+
/* interface to libsectok */
static int
@@ -193,6 +199,7 @@ sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
int padding)
{
u_char *padded = NULL;
+ u_char aut0[EVP_MAX_MD_SIZE];
int sw, len, olen, status = -1;
debug("sc_private_decrypt called");
@@ -209,17 +216,31 @@ sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
len = BN_num_bytes(rsa->n);
padded = xmalloc(len);
- sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, (u_char *)from,
- 0, NULL, &sw);
- if (!sectok_swOK(sw)) {
- error("sc_private_decrypt: INS_DECRYPT failed: %s",
- sectok_get_sw(sw));
- goto err;
+ sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
+
+ if (sw == 0x6982) {
+ /* permission denied; try PIN if provided */
+ if (sc_pin && strlen(sc_pin) > 0) {
+ sc_mk_digest(sc_pin, aut0);
+ if (cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) {
+ error("smartcard passphrase incorrect");
+ goto err;
+ }
+ } else {
+ /* try default AUT0 key */
+ if (cyberflex_verify_AUT0(sc_fd, cla, DEFAUT0, 8) < 0) {
+ /* default AUT0 key failed; prompt for passphrase */
+ if (get_AUT0(aut0) < 0 ||
+ cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) {
+ error("smartcard passphrase incorrect");
+ goto err;
+ }
+ }
+ }
+ sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
}
- sectok_apdu(sc_fd, CLA_SSH, INS_GET_RESPONSE, 0, 0, 0, NULL,
- len, padded, &sw);
if (!sectok_swOK(sw)) {
- error("sc_private_decrypt: INS_GET_RESPONSE failed: %s",
+ error("sc_private_decrypt: INS_DECRYPT failed: %s",
sectok_get_sw(sw));
goto err;
}
@@ -256,19 +277,12 @@ sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa,
error("RSA_padding_add_PKCS1_type_1 failed");
goto err;
}
- sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, 0, NULL, &sw);
+ sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw);
if (!sectok_swOK(sw)) {
error("sc_private_decrypt: INS_DECRYPT failed: %s",
sectok_get_sw(sw));
goto err;
}
- sectok_apdu(sc_fd, CLA_SSH, INS_GET_RESPONSE, 0, 0, 0, NULL,
- len, to, &sw);
- if (!sectok_swOK(sw)) {
- error("sc_private_decrypt: INS_GET_RESPONSE failed: %s",
- sectok_get_sw(sw));
- goto err;
- }
err:
if (padded)
xfree(padded);
@@ -340,7 +354,7 @@ sc_close(void)
}
Key *
-sc_get_key(const char *id)
+sc_get_key(const char *id, const char *pin)
{
Key *k;
int status;
@@ -349,6 +363,10 @@ sc_get_key(const char *id)
xfree(sc_reader_id);
sc_reader_id = xstrdup(id);
+ if (sc_pin != NULL)
+ xfree(sc_pin);
+ sc_pin = (pin == NULL) ? NULL : xstrdup(pin);
+
k = key_new(KEY_RSA);
if (k == NULL) {
return NULL;
@@ -376,19 +394,30 @@ sc_get_key(const char *id)
goto done; \
} while (0)
-static int
-get_AUT0(char *aut0)
+static void
+sc_mk_digest(const char *pin, u_char *digest)
{
const EVP_MD *evp_md = EVP_sha1();
EVP_MD_CTX md;
+
+ EVP_DigestInit(&md, evp_md);
+ EVP_DigestUpdate(&md, pin, strlen(pin));
+ EVP_DigestFinal(&md, digest, NULL);
+}
+
+static int
+get_AUT0(u_char *aut0)
+{
char *pass;
pass = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN);
if (pass == NULL)
return -1;
- EVP_DigestInit(&md, evp_md);
- EVP_DigestUpdate(&md, pass, strlen(pass));
- EVP_DigestFinal(&md, aut0, NULL);
+ if (!strcmp(pass, "-")) {
+ memcpy(aut0, DEFAUT0, sizeof DEFAUT0);
+ return 0;
+ }
+ sc_mk_digest(pass, aut0);
memset(pass, 0, strlen(pass));
xfree(pass);
return 0;
@@ -399,7 +428,6 @@ sc_put_key(Key *prv, const char *id)
{
u_char *elements[NUM_RSA_KEY_ELEMENTS];
u_char key_fid[2];
- u_char DEFAUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63};
u_char AUT0[EVP_MAX_MD_SIZE];
int len, status = -1, i, fd = -1, ret;
int sw = 0, cla = 0x00;
@@ -436,10 +464,12 @@ sc_put_key(Key *prv, const char *id)
if (cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
if (get_AUT0(AUT0) < 0 ||
cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
- error("cyberflex_verify_AUT0 failed");
+ memset(AUT0, 0, sizeof(DEFAUT0));
+ error("smartcard passphrase incorrect");
goto done;
}
}
+ memset(AUT0, 0, sizeof(DEFAUT0));
key_fid[0] = 0x00;
key_fid[1] = 0x12;
if (cyberflex_load_rsa_priv(fd, cla, key_fid, 5, 8*len, elements,
diff --git a/usr.bin/ssh/scard.h b/usr.bin/ssh/scard.h
index c46eae1be66..465fe274bd4 100644
--- a/usr.bin/ssh/scard.h
+++ b/usr.bin/ssh/scard.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: scard.h,v 1.8 2002/03/21 16:54:53 markus Exp $ */
+/* $OpenBSD: scard.h,v 1.9 2002/03/21 21:54:34 rees Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -35,7 +35,7 @@
#define SCARD_ERROR_NOCARD -2
#define SCARD_ERROR_APPLET -3
-Key *sc_get_key(const char*);
+Key *sc_get_key(const char*, const char*);
ENGINE *sc_get_engine(void);
void sc_close(void);
int sc_put_key(Key *, const char*);
diff --git a/usr.bin/ssh/ssh-keygen.c b/usr.bin/ssh/ssh-keygen.c
index 73817a63b05..a0f0c9a7fb1 100644
--- a/usr.bin/ssh/ssh-keygen.c
+++ b/usr.bin/ssh/ssh-keygen.c
@@ -12,7 +12,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: ssh-keygen.c,v 1.95 2002/03/21 16:54:53 markus Exp $");
+RCSID("$OpenBSD: ssh-keygen.c,v 1.96 2002/03/21 21:54:34 rees Exp $");
#include <openssl/evp.h>
#include <openssl/pem.h>
@@ -414,7 +414,7 @@ do_download(struct passwd *pw, const char *sc_reader_id)
{
Key *pub = NULL;
- pub = sc_get_key(sc_reader_id);
+ pub = sc_get_key(sc_reader_id, NULL);
if (pub == NULL)
fatal("cannot read public key from smartcard");
key_write(pub, stdout);