diff options
author | Jim Rees <rees@cvs.openbsd.org> | 2002-03-21 21:54:35 +0000 |
---|---|---|
committer | Jim Rees <rees@cvs.openbsd.org> | 2002-03-21 21:54:35 +0000 |
commit | 1e6c115eddb5e1954bd09d83a9a50c20390be545 (patch) | |
tree | 7ef8b29970258c1c6988b22225f8010639bd658e | |
parent | 74d71a21f81699632a7d334453274a14937cad55 (diff) |
Add PIN-protection for secret key.
-rw-r--r-- | usr.bin/ssh/scard.c | 84 | ||||
-rw-r--r-- | usr.bin/ssh/scard.h | 4 | ||||
-rw-r--r-- | usr.bin/ssh/ssh-keygen.c | 4 |
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); |