]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
- rees@cvs.openbsd.org 2002/03/21 21:54:34
authorBen Lindstrom <mouring@eviladmin.org>
Fri, 22 Mar 2002 03:47:38 +0000 (03:47 +0000)
committerBen Lindstrom <mouring@eviladmin.org>
Fri, 22 Mar 2002 03:47:38 +0000 (03:47 +0000)
     [scard.c scard.h ssh-keygen.c]
     Add PIN-protection for secret key.

ChangeLog
scard.c
scard.h
ssh-keygen.c

index 54228ff27d8423545fb66eb591977e04fd310a2b..5e4d14907002c5296ba0b936d6d8fae49824af58 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
    - 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,
  - 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 9d044acb9557c630000fcd54d777c17f0d8b76e1..a8ee2fe6d7bdbc6c32573239b58b33c955f512f1 100644 (file)
--- 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 <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/scard.h b/scard.h
index c46eae1be66e0ce7ad332807d553b27f7a1ac088..465fe274bd43c4c4c521c1919e5bf773a7016f21 100644 (file)
--- 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*);
index d14c9900450efb7e3c56c3b239ed9a8a028c8d6f..7d36293659098fd87b8a5c18b24d562d91087b86 100644 (file)
@@ -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>
@@ -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);