version 1.21, 2002/03/21 18:08:15 |
version 1.22, 2002/03/21 21:54:34 |
|
|
#include "key.h" |
#include "key.h" |
#include "log.h" |
#include "log.h" |
#include "xmalloc.h" |
#include "xmalloc.h" |
#include "scard.h" |
|
#include "readpass.h" |
#include "readpass.h" |
|
#include "scard.h" |
|
|
#ifdef OPENSSL_VERSION_NUMBER |
#ifdef OPENSSL_VERSION_NUMBER |
#if OPENSSL_VERSION_NUMBER >= 0x00907000L |
#if OPENSSL_VERSION_NUMBER >= 0x00907000L |
|
|
|
|
#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); |
|
|
/* interface to libsectok */ |
/* interface to libsectok */ |
|
|
static int |
static int |
|
|
int padding) |
int padding) |
{ |
{ |
u_char *padded = NULL; |
u_char *padded = NULL; |
|
u_char aut0[EVP_MAX_MD_SIZE]; |
int sw, len, olen, status = -1; |
int sw, len, olen, status = -1; |
|
|
debug("sc_private_decrypt called"); |
debug("sc_private_decrypt called"); |
|
|
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, (u_char *)from, |
sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw); |
0, NULL, &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); |
|
} |
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: |
|
|
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, 0, NULL, &sw); |
sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &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, to, &sw); |
|
if (!sectok_swOK(sw)) { |
|
error("sc_private_decrypt: INS_GET_RESPONSE failed: %s", |
|
sectok_get_sw(sw)); |
|
goto err; |
|
} |
|
err: |
err: |
if (padded) |
if (padded) |
xfree(padded); |
xfree(padded); |
|
|
} |
} |
|
|
Key * |
Key * |
sc_get_key(const char *id) |
sc_get_key(const char *id, const char *pin) |
{ |
{ |
Key *k; |
Key *k; |
int status; |
int status; |
|
|
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; |
|
|
goto done; \ |
goto done; \ |
} while (0) |
} while (0) |
|
|
static int |
static void |
get_AUT0(char *aut0) |
sc_mk_digest(const char *pin, u_char *digest) |
{ |
{ |
const EVP_MD *evp_md = EVP_sha1(); |
const EVP_MD *evp_md = EVP_sha1(); |
EVP_MD_CTX md; |
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; |
char *pass; |
|
|
pass = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN); |
pass = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN); |
if (pass == NULL) |
if (pass == NULL) |
return -1; |
return -1; |
EVP_DigestInit(&md, evp_md); |
if (!strcmp(pass, "-")) { |
EVP_DigestUpdate(&md, pass, strlen(pass)); |
memcpy(aut0, DEFAUT0, sizeof DEFAUT0); |
EVP_DigestFinal(&md, aut0, NULL); |
return 0; |
|
} |
|
sc_mk_digest(pass, aut0); |
memset(pass, 0, strlen(pass)); |
memset(pass, 0, strlen(pass)); |
xfree(pass); |
xfree(pass); |
return 0; |
return 0; |
|
|
{ |
{ |
u_char *elements[NUM_RSA_KEY_ELEMENTS]; |
u_char *elements[NUM_RSA_KEY_ELEMENTS]; |
u_char key_fid[2]; |
u_char key_fid[2]; |
u_char DEFAUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63}; |
|
u_char AUT0[EVP_MAX_MD_SIZE]; |
u_char AUT0[EVP_MAX_MD_SIZE]; |
int len, status = -1, i, fd = -1, ret; |
int len, status = -1, i, fd = -1, ret; |
int sw = 0, cla = 0x00; |
int sw = 0, cla = 0x00; |
|
|
if (cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) { |
if (cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) { |
if (get_AUT0(AUT0) < 0 || |
if (get_AUT0(AUT0) < 0 || |
cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 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; |
goto done; |
} |
} |
} |
} |
|
memset(AUT0, 0, sizeof(DEFAUT0)); |
key_fid[0] = 0x00; |
key_fid[0] = 0x00; |
key_fid[1] = 0x12; |
key_fid[1] = 0x12; |
if (cyberflex_load_rsa_priv(fd, cla, key_fid, 5, 8*len, elements, |
if (cyberflex_load_rsa_priv(fd, cla, key_fid, 5, 8*len, elements, |