From 266ec63eb36e2d3154ead355ce67cdee5c9394a3 Mon Sep 17 00:00:00 2001 From: Ben Lindstrom Date: Fri, 22 Mar 2002 03:47:38 +0000 Subject: - rees@cvs.openbsd.org 2002/03/21 21:54:34 [scard.c scard.h ssh-keygen.c] Add PIN-protection for secret key. --- ChangeLog | 5 +++- scard.c | 84 +++++++++++++++++++++++++++++++++++++++++------------------- scard.h | 4 +-- ssh-keygen.c | 4 +-- 4 files changed, 65 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index 54228ff27..5e4d14907 100644 --- a/ChangeLog +++ b/ChangeLog @@ -136,6 +136,9 @@ - markus@cvs.openbsd.org 2002/03/21 21:23:34 [sshd.c] add privsep_preauth() and remove 1 goto; ok provos@ + - rees@cvs.openbsd.org 2002/03/21 21:54:34 + [scard.c scard.h ssh-keygen.c] + Add PIN-protection for secret key. 20020317 - (tim) [configure.ac] Assume path given with --with-pid-dir=PATH is wanted, @@ -7982,4 +7985,4 @@ - Wrote replacements for strlcpy and mkdtemp - Released 1.0pre1 -$Id: ChangeLog,v 1.1963 2002/03/22 03:43:46 mouring Exp $ +$Id: ChangeLog,v 1.1964 2002/03/22 03:47:38 mouring Exp $ diff --git a/scard.c b/scard.c index 9d044acb9..a8ee2fe6d 100644 --- a/scard.c +++ b/scard.c @@ -24,7 +24,7 @@ #include "includes.h" #ifdef SMARTCARD -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 #include @@ -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/scard.h b/scard.h index c46eae1be..465fe274b 100644 --- a/scard.h +++ b/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/ssh-keygen.c b/ssh-keygen.c index d14c99004..7d3629365 100644 --- a/ssh-keygen.c +++ b/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 #include @@ -418,7 +418,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); -- cgit v1.2.3