[BACK]Return to scard.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/Attic/scard.c between version 1.15.2.3 and 1.16

version 1.15.2.3, 2002/06/26 18:22:35 version 1.16, 2001/12/19 07:18:56
Line 26 
Line 26 
 #include "includes.h"  #include "includes.h"
 RCSID("$OpenBSD$");  RCSID("$OpenBSD$");
   
 #include <openssl/evp.h>  #include <openssl/engine.h>
 #include <sectok.h>  #include <sectok.h>
   
 #include "key.h"  #include "key.h"
 #include "log.h"  #include "log.h"
 #include "xmalloc.h"  #include "xmalloc.h"
 #include "readpass.h"  
 #include "scard.h"  #include "scard.h"
   
 #if OPENSSL_VERSION_NUMBER < 0x00907000L  
 #define USE_ENGINE  
 #define RSA_get_default_method RSA_get_default_openssl_method  
 #else  
 #endif  
   
 #ifdef USE_ENGINE  
 #include <openssl/engine.h>  
 #define sc_get_rsa sc_get_engine  
 #else  
 #define sc_get_rsa sc_get_rsa_method  
 #endif  
   
 #define CLA_SSH 0x05  #define CLA_SSH 0x05
 #define INS_DECRYPT 0x10  #define INS_DECRYPT 0x10
 #define INS_GET_KEYLENGTH 0x20  #define INS_GET_KEYLENGTH 0x20
Line 56 
Line 42 
   
 #define MAX_BUF_SIZE 256  #define MAX_BUF_SIZE 256
   
 u_char DEFAUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63};  
   
 static int sc_fd = -1;  static int sc_fd = -1;
 static char *sc_reader_id = NULL;  static char *sc_reader_id = NULL;
 static char *sc_pin = NULL;  
 static int cla = 0x00;  /* class */  static int cla = 0x00;  /* class */
   
 static void sc_mk_digest(const char *pin, u_char *digest);  
 static int get_AUT0(u_char *aut0);  
 static int try_AUT0(void);  
   
 /* interface to libsectok */  /* interface to libsectok */
   
 static int  static int
Line 147 
Line 126 
         n = NULL;          n = NULL;
   
         if (sc_fd < 0) {          if (sc_fd < 0) {
                 if (sc_init() < 0)                  status = sc_init();
                   if (status < 0 )
                         goto err;                          goto err;
         }          }
   
Line 165 
Line 145 
         n = xmalloc(len);          n = xmalloc(len);
         /* get n */          /* get n */
         sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw);          sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw);
   
         if (sw == 0x6982) {  
                 if (try_AUT0() < 0)  
                         goto err;  
                 sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw);  
         }  
         if (!sectok_swOK(sw)) {          if (!sectok_swOK(sw)) {
                 error("could not obtain public key: %s", sectok_get_sw(sw));                  error("could not obtain public key: %s", sectok_get_sw(sw));
                 goto err;                  goto err;
Line 191 
Line 165 
   
         status = 0;          status = 0;
         p = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX);          p = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX);
         debug("fingerprint %u %s", key_size(k), p);          debug("fingerprint %d %s", key_size(k), p);
         xfree(p);          xfree(p);
   
 err:  err:
Line 204 
Line 178 
 /* private key operations */  /* private key operations */
   
 static int  static int
 sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,  sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding)
     int padding)  
 {  {
         u_char *padded = NULL;          u_char *padded = NULL;
         int sw, len, olen, status = -1;          int sw, len, olen, status = -1;
Line 224 
Line 197 
         len = BN_num_bytes(rsa->n);          len = BN_num_bytes(rsa->n);
         padded = xmalloc(len);          padded = xmalloc(len);
   
         sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);          sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, 0, NULL, &sw);
   
         if (sw == 0x6982) {  
                 if (try_AUT0() < 0)  
                         goto err;  
                 sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);  
         }  
         if (!sectok_swOK(sw)) {          if (!sectok_swOK(sw)) {
                 error("sc_private_decrypt: INS_DECRYPT failed: %s",                  error("sc_private_decrypt: INS_DECRYPT failed: %s",
                     sectok_get_sw(sw));                      sectok_get_sw(sw));
                 goto err;                  goto err;
         }          }
           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",
                       sectok_get_sw(sw));
                   goto err;
           }
         olen = RSA_padding_check_PKCS1_type_2(to, len, padded + 1, len - 1,          olen = RSA_padding_check_PKCS1_type_2(to, len, padded + 1, len - 1,
             len);              len);
 err:  err:
Line 246 
Line 220 
 }  }
   
 static int  static int
 sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa,  sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding)
     int padding)  
 {  {
         u_char *padded = NULL;          u_char *padded = NULL;
         int sw, len, status = -1;          int sw, len, status = -1;
Line 265 
Line 238 
         len = BN_num_bytes(rsa->n);          len = BN_num_bytes(rsa->n);
         padded = xmalloc(len);          padded = xmalloc(len);
   
         if (RSA_padding_add_PKCS1_type_1(padded, len, (u_char *)from, flen) <= 0) {          if (RSA_padding_add_PKCS1_type_1(padded, len, from, flen) <= 0) {
                 error("RSA_padding_add_PKCS1_type_1 failed");                  error("RSA_padding_add_PKCS1_type_1 failed");
                 goto err;                  goto err;
         }          }
         sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw);          sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, 0, NULL, &sw);
         if (sw == 0x6982) {          if (!sectok_swOK(sw)) {
                 if (try_AUT0() < 0)                  error("sc_private_decrypt: INS_DECRYPT failed: %s",
                         goto err;                      sectok_get_sw(sw));
                 sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw);                  goto err;
         }          }
           sectok_apdu(sc_fd, CLA_SSH, INS_GET_RESPONSE, 0, 0, 0, NULL,
               len, to, &sw);
         if (!sectok_swOK(sw)) {          if (!sectok_swOK(sw)) {
                 error("sc_private_encrypt: INS_DECRYPT failed: %s",                  error("sc_private_decrypt: INS_GET_RESPONSE failed: %s",
                     sectok_get_sw(sw));                      sectok_get_sw(sw));
                 goto err;                  goto err;
         }          }
Line 300 
Line 275 
         return 1;          return 1;
 }  }
   
   
 /* engine for overloading private key operations */  /* engine for overloading private key operations */
   
 static RSA_METHOD *  static ENGINE *smart_engine = NULL;
 sc_get_rsa_method(void)  static RSA_METHOD smart_rsa =
 {  {
         static RSA_METHOD smart_rsa;          "sectok",
         const RSA_METHOD *def = RSA_get_default_method();          NULL,
           NULL,
           NULL,
           NULL,
           NULL,
           NULL,
           NULL,
           NULL,
           0,
           NULL,
   };
   
         /* use the OpenSSL version */  ENGINE *
         memcpy(&smart_rsa, def, sizeof(smart_rsa));  sc_get_engine(void)
   {
           RSA_METHOD *def;
   
         smart_rsa.name          = "sectok";          def = RSA_get_default_openssl_method();
   
         /* overload */          /* overload */
         smart_rsa.rsa_priv_enc  = sc_private_encrypt;          smart_rsa.rsa_priv_enc  = sc_private_encrypt;
Line 321 
Line 309 
         orig_finish             = def->finish;          orig_finish             = def->finish;
         smart_rsa.finish        = sc_finish;          smart_rsa.finish        = sc_finish;
   
         return &smart_rsa;          /* just use the OpenSSL version */
 }          smart_rsa.rsa_pub_enc   = def->rsa_pub_enc;
           smart_rsa.rsa_pub_dec   = def->rsa_pub_dec;
           smart_rsa.rsa_mod_exp   = def->rsa_mod_exp;
           smart_rsa.bn_mod_exp    = def->bn_mod_exp;
           smart_rsa.init          = def->init;
           smart_rsa.flags         = def->flags;
           smart_rsa.app_data      = def->app_data;
           smart_rsa.rsa_sign      = def->rsa_sign;
           smart_rsa.rsa_verify    = def->rsa_verify;
   
 #ifdef USE_ENGINE          smart_engine = ENGINE_new();
 static ENGINE *  
 sc_get_engine(void)  
 {  
         static ENGINE *smart_engine = NULL;  
   
         if ((smart_engine = ENGINE_new()) == NULL)  
                 fatal("ENGINE_new failed");  
   
         ENGINE_set_id(smart_engine, "sectok");          ENGINE_set_id(smart_engine, "sectok");
         ENGINE_set_name(smart_engine, "libsectok");          ENGINE_set_name(smart_engine, "libsectok");
           ENGINE_set_RSA(smart_engine, &smart_rsa);
         ENGINE_set_RSA(smart_engine, sc_get_rsa_method());  
         ENGINE_set_DSA(smart_engine, DSA_get_default_openssl_method());          ENGINE_set_DSA(smart_engine, DSA_get_default_openssl_method());
         ENGINE_set_DH(smart_engine, DH_get_default_openssl_method());          ENGINE_set_DH(smart_engine, DH_get_default_openssl_method());
         ENGINE_set_RAND(smart_engine, RAND_SSLeay());          ENGINE_set_RAND(smart_engine, RAND_SSLeay());
Line 344 
Line 332 
   
         return smart_engine;          return smart_engine;
 }  }
 #endif  
   
 void  void
 sc_close(void)  sc_close(void)
Line 355 
Line 342 
         }          }
 }  }
   
 Key **  Key *
 sc_get_keys(const char *id, const char *pin)  sc_get_key(const char *id)
 {  {
         Key *k, *n, **keys;          Key *k;
         int status, nkeys = 2;          int status;
   
         if (sc_reader_id != NULL)          if (sc_reader_id != NULL)
                 xfree(sc_reader_id);                  xfree(sc_reader_id);
         sc_reader_id = xstrdup(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);          k = key_new(KEY_RSA);
         if (k == NULL) {          if (k == NULL) {
                 return NULL;                  return NULL;
Line 383 
Line 366 
                 key_free(k);                  key_free(k);
                 return NULL;                  return NULL;
         }          }
         keys = xmalloc((nkeys+1) * sizeof(Key *));          return k;
   
         n = key_new(KEY_RSA1);  
         BN_copy(n->rsa->n, k->rsa->n);  
         BN_copy(n->rsa->e, k->rsa->e);  
         RSA_set_method(n->rsa, sc_get_rsa());  
         n->flags |= KEY_FLAG_EXT;  
         keys[0] = n;  
   
         n = key_new(KEY_RSA);  
         BN_copy(n->rsa->n, k->rsa->n);  
         BN_copy(n->rsa->e, k->rsa->e);  
         RSA_set_method(n->rsa, sc_get_rsa());  
         n->flags |= KEY_FLAG_EXT;  
         keys[1] = n;  
   
         keys[2] = NULL;  
   
         key_free(k);  
         return keys;  
 }  
   
 #define NUM_RSA_KEY_ELEMENTS 5+1  
 #define COPY_RSA_KEY(x, i) \  
         do { \  
                 len = BN_num_bytes(prv->rsa->x); \  
                 elements[i] = xmalloc(len); \  
                 debug("#bytes %d", len); \  
                 if (BN_bn2bin(prv->rsa->x, elements[i]) < 0) \  
                         goto done; \  
         } while (0)  
   
 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;  
         if (!strcmp(pass, "-")) {  
                 memcpy(aut0, DEFAUT0, sizeof DEFAUT0);  
                 return 0;  
         }  
         sc_mk_digest(pass, aut0);  
         memset(pass, 0, strlen(pass));  
         xfree(pass);  
         return 0;  
 }  
   
 static int  
 try_AUT0(void)  
 {  
         u_char aut0[EVP_MAX_MD_SIZE];  
   
         /* 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");  
                         return (-1);  
                 }  
         } 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");  
                                 return (-1);  
                         }  
                 }  
         }  
         return (0);  
 }  
   
 int  
 sc_put_key(Key *prv, const char *id)  
 {  
         u_char *elements[NUM_RSA_KEY_ELEMENTS];  
         u_char key_fid[2];  
         u_char AUT0[EVP_MAX_MD_SIZE];  
         int len, status = -1, i, fd = -1, ret;  
         int sw = 0, cla = 0x00;  
   
         for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)  
                 elements[i] = NULL;  
   
         COPY_RSA_KEY(q, 0);  
         COPY_RSA_KEY(p, 1);  
         COPY_RSA_KEY(iqmp, 2);  
         COPY_RSA_KEY(dmq1, 3);  
         COPY_RSA_KEY(dmp1, 4);  
         COPY_RSA_KEY(n, 5);  
         len = BN_num_bytes(prv->rsa->n);  
         fd = sectok_friendly_open(id, STONOWAIT, &sw);  
         if (fd < 0) {  
                 error("sectok_open failed: %s", sectok_get_sw(sw));  
                 goto done;  
         }  
         if (! sectok_cardpresent(fd)) {  
                 error("smartcard in reader %s not present", id);  
                 goto done;  
         }  
         ret = sectok_reset(fd, 0, NULL, &sw);  
         if (ret <= 0) {  
                 error("sectok_reset failed: %s", sectok_get_sw(sw));  
                 goto done;  
         }  
         if ((cla = cyberflex_inq_class(fd)) < 0) {  
                 error("cyberflex_inq_class failed");  
                 goto done;  
         }  
         memcpy(AUT0, DEFAUT0, sizeof(DEFAUT0));  
         if (cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {  
                 if (get_AUT0(AUT0) < 0 ||  
                     cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {  
                         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,  
             &sw) < 0) {  
                 error("cyberflex_load_rsa_priv failed: %s", sectok_get_sw(sw));  
                 goto done;  
         }  
         if (!sectok_swOK(sw))  
                 goto done;  
         log("cyberflex_load_rsa_priv done");  
         key_fid[0] = 0x73;  
         key_fid[1] = 0x68;  
         if (cyberflex_load_rsa_pub(fd, cla, key_fid, len, elements[5],  
             &sw) < 0) {  
                 error("cyberflex_load_rsa_pub failed: %s", sectok_get_sw(sw));  
                 goto done;  
         }  
         if (!sectok_swOK(sw))  
                 goto done;  
         log("cyberflex_load_rsa_pub done");  
         status = 0;  
   
 done:  
         memset(elements[0], '\0', BN_num_bytes(prv->rsa->q));  
         memset(elements[1], '\0', BN_num_bytes(prv->rsa->p));  
         memset(elements[2], '\0', BN_num_bytes(prv->rsa->iqmp));  
         memset(elements[3], '\0', BN_num_bytes(prv->rsa->dmq1));  
         memset(elements[4], '\0', BN_num_bytes(prv->rsa->dmp1));  
         memset(elements[5], '\0', BN_num_bytes(prv->rsa->n));  
   
         for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)  
                 if (elements[i])  
                         xfree(elements[i]);  
         if (fd != -1)  
                 sectok_close(fd);  
         return (status);  
 }  }
 #endif /* SMARTCARD */  #endif /* SMARTCARD */

Legend:
Removed from v.1.15.2.3  
changed lines
  Added in v.1.16