From 2ac6b811a542680153b820fc1a59d3ffd0561ea9 Mon Sep 17 00:00:00 2001 From: jey Date: Wed, 21 Nov 2001 21:19:58 +0000 Subject: [PATCH] - added install target to libsc Makefile - added a few functions - added a patch against OpenSSH 3.0.1p1 to enable libsc support git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@48 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/opensc-pkcs15.h | 13 +++++++++++- src/libopensc/pkcs15-cert.c | 19 +++++++++++++++++ src/libopensc/pkcs15-sec.c | 39 ++++++++++++++++++++++++++++++++--- src/libopensc/pkcs15.h | 13 +++++++++++- src/libopensc/sc.c | 3 +-- src/openssh/README | 27 ++++++++++++++++++++++++ src/openssh/opensc-ssh.c | 13 +++++++++++- 7 files changed, 119 insertions(+), 8 deletions(-) create mode 100644 src/openssh/README diff --git a/src/libopensc/opensc-pkcs15.h b/src/libopensc/opensc-pkcs15.h index 57a313be..0c014805 100644 --- a/src/libopensc/opensc-pkcs15.h +++ b/src/libopensc/opensc-pkcs15.h @@ -161,7 +161,15 @@ int sc_pkcs15_destroy(struct sc_pkcs15_card *card); int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_prkey_info *prkey, - const u8 * in, int inlen, u8 *out, int outlen); + const u8 *in, int inlen, u8 *out, int outlen); + +#define SC_PKCS15_HASH_NONE 0 +#define SC_PKCS15_HASH_SHA1 1 + +int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, + const struct sc_pkcs15_prkey_info *prkey, + int hash, const u8 *in, int inlen, u8 *out, + int outlen); void sc_pkcs15_print_card(const struct sc_pkcs15_card *card); @@ -171,6 +179,9 @@ int sc_pkcs15_read_certificate(struct sc_pkcs15_card *card, const struct sc_pkcs15_cert_info *info, struct sc_pkcs15_cert **cert); void sc_pkcs15_free_certificate(struct sc_pkcs15_cert *cert); +int sc_pkcs15_find_cert_by_id(struct sc_pkcs15_card *card, + const struct sc_pkcs15_id *id, + struct sc_pkcs15_cert_info **out); void sc_pkcs15_print_prkey_info(const struct sc_pkcs15_prkey_info *prkey); int sc_pkcs15_enum_private_keys(struct sc_pkcs15_card *card); diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c index d4ae7f61..26bed7fc 100644 --- a/src/libopensc/pkcs15-cert.c +++ b/src/libopensc/pkcs15-cert.c @@ -321,3 +321,22 @@ void sc_pkcs15_free_certificate(struct sc_pkcs15_cert *cert) free(cert->data); free(cert); } + +int sc_pkcs15_find_cert_by_id(struct sc_pkcs15_card *card, + const struct sc_pkcs15_id *id, + struct sc_pkcs15_cert_info **cert_out) +{ + int r, i; + + r = sc_pkcs15_enum_certificates(card); + if (r < 0) + return r; + for (i = 0; i < card->cert_count; i++) { + struct sc_pkcs15_cert_info *cert = &card->cert_info[i]; + if (sc_pkcs15_compare_id(&cert->id, id) == 1) { + *cert_out = cert; + return 0; + } + } + return SC_ERROR_OBJECT_NOT_FOUND; +} diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 8a9e4d00..ee5ab9e6 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -32,7 +32,6 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card, int r; struct sc_security_env senv; - senv.algorithm_ref = 0x02; senv.key_file_id = prkey->file_id; senv.signature = 0; @@ -49,8 +48,42 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card, if (r) return r; r = sc_decipher(p15card->card, in, inlen, out, outlen); + + return r; +} + +int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, + const struct sc_pkcs15_prkey_info *prkey, + int hash, const u8 *in, int inlen, u8 *out, + int outlen) +{ + int r; + struct sc_security_env senv; + + senv.algorithm_ref = 0x02; + switch (hash) { + case SC_PKCS15_HASH_SHA1: + senv.algorithm_ref |= 0x10; + break; + case SC_PKCS15_HASH_NONE: + default: + break; + } + senv.key_file_id = prkey->file_id; + senv.signature = 1; + senv.key_ref = prkey->key_reference; + + r = sc_select_file(p15card->card, &p15card->file_app, + &p15card->file_app.path, SC_SELECT_FILE_BY_PATH); if (r) return r; - - return 0; + r = sc_restore_security_env(p15card->card, 0); /* empty SE */ + if (r) + return r; + r = sc_set_security_env(p15card->card, &senv); + if (r) + return r; + r = sc_compute_signature(p15card->card, in, inlen, out, outlen); + + return r; } diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 57a313be..0c014805 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -161,7 +161,15 @@ int sc_pkcs15_destroy(struct sc_pkcs15_card *card); int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_prkey_info *prkey, - const u8 * in, int inlen, u8 *out, int outlen); + const u8 *in, int inlen, u8 *out, int outlen); + +#define SC_PKCS15_HASH_NONE 0 +#define SC_PKCS15_HASH_SHA1 1 + +int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, + const struct sc_pkcs15_prkey_info *prkey, + int hash, const u8 *in, int inlen, u8 *out, + int outlen); void sc_pkcs15_print_card(const struct sc_pkcs15_card *card); @@ -171,6 +179,9 @@ int sc_pkcs15_read_certificate(struct sc_pkcs15_card *card, const struct sc_pkcs15_cert_info *info, struct sc_pkcs15_cert **cert); void sc_pkcs15_free_certificate(struct sc_pkcs15_cert *cert); +int sc_pkcs15_find_cert_by_id(struct sc_pkcs15_card *card, + const struct sc_pkcs15_id *id, + struct sc_pkcs15_cert_info **out); void sc_pkcs15_print_prkey_info(const struct sc_pkcs15_prkey_info *prkey); int sc_pkcs15_enum_private_keys(struct sc_pkcs15_card *card); diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index c6f93108..e475261e 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -587,8 +587,7 @@ int sc_establish_context(struct sc_context **ctx_out) &ctx->pcsc_ctx); if (rv != SCARD_S_SUCCESS) { if (sc_debug) { - fprintf(stderr, - "ERROR: Cannot connect to Resource Manager\n"); + fprintf(stderr, "ERROR: Cannot connect to Resource Manager\n"); } return SC_ERROR_CONNECTING_TO_RES_MGR; } diff --git a/src/openssh/README b/src/openssh/README new file mode 100644 index 00000000..95543d78 --- /dev/null +++ b/src/openssh/README @@ -0,0 +1,27 @@ + +Steps for your OpenSSH pleasure: + +- Download, compile and install openssl-engine (http://www.openssl.org) +- Download OpenSSH 3.0.1p1 (http://www.openssh.com) +- Apply 'openssh-3.0.1p1-patch.diff' from this directory +- Run autoconf and autoheader +- Run configure with the argument '--with-libsc' +- Change the hardcoded PIN to the one set on your card... =) + The line to modify can be found in file scard-libsc.c. + (This will be fixed in the future) +- Compile and install + +- Extract a public key from your SmartCard in OpenSSH format + (e.g. with 'sc-ssh -c -k -o ') +- Transfer the public key to desired server +- Run OpenSSH with 'ssh -I [:] ' + (e.g. '-I 0:45' uses first available reader and certificate with + ID 45h, '-I 0' uses the first found certificate') + +With luck you should be authenticated and ready to go. If it won't work, +try enabling debug information with the '-d' switch. + +NOTE: ssh-agent should also work. + +-- +Juha Yrjölä diff --git a/src/openssh/opensc-ssh.c b/src/openssh/opensc-ssh.c index b2442567..54630304 100644 --- a/src/openssh/opensc-ssh.c +++ b/src/openssh/opensc-ssh.c @@ -123,6 +123,7 @@ int write_ssh_key(struct sc_pkcs15_cert_info *cinfo, RSA *rsa) { u8 *buf = malloc(10240), *p = buf, *num; int r, len, skip, left = 10240; + FILE *outf; if (buf == NULL) return 1; @@ -151,7 +152,17 @@ int write_ssh_key(struct sc_pkcs15_cert_info *cinfo, RSA *rsa) fprintf(stderr, "Base64 encoding failed: %s\n", sc_strerror(r)); return 1; } - printf("ssh-rsa %s libsc-cert-%02X\n", p, cinfo->id.value[0]); + if (opt_outfile == NULL) + outf = stdin; + else { + outf = fopen(opt_outfile, "w"); + if (outf == NULL) { + fprintf(stderr, "Unable to open '%s' for writing.\n", + opt_outfile); + return 2; + } + } + fprintf(outf, "ssh-rsa %s libsc-cert-%02X\n", p, cinfo->id.value[0]); free(p), free(buf); return 0;