summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--INSTALL6
-rw-r--r--Makefile.in4
-rw-r--r--README.smartcard12
-rw-r--r--acconfig.h8
-rw-r--r--configure.ac43
-rw-r--r--scard-opensc.c462
-rw-r--r--scard.c4
8 files changed, 530 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 0674792e3..8dfd9fa75 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
120020405
2 - (bal) Patch for OpenSC SmartCard library; ok markus@; patch by
3 Juha Yrjölä <jyrjola@cc.hut.fi>
4 - (bal) Minor documentation update to reflect smartcard library
5 support changes.
6
120020404 720020404
2 - (stevesk) [auth-pam.c auth-pam.h auth-passwd.c auth-sia.c auth-sia.h 8 - (stevesk) [auth-pam.c auth-pam.h auth-passwd.c auth-sia.c auth-sia.h
3 auth1.c auth2.c] PAM, OSF_SIA password auth cleanup; from djm. 9 auth1.c auth2.c] PAM, OSF_SIA password auth cleanup; from djm.
@@ -8155,4 +8161,4 @@
8155 - Wrote replacements for strlcpy and mkdtemp 8161 - Wrote replacements for strlcpy and mkdtemp
8156 - Released 1.0pre1 8162 - Released 1.0pre1
8157 8163
8158$Id: ChangeLog,v 1.2022 2002/04/04 22:10:38 mouring Exp $ 8164$Id: ChangeLog,v 1.2023 2002/04/05 16:11:45 mouring Exp $
diff --git a/INSTALL b/INSTALL
index 9159248cb..35c6c749c 100644
--- a/INSTALL
+++ b/INSTALL
@@ -178,6 +178,10 @@ are installed.
178--with-4in6 Check for IPv4 in IPv6 mapped addresses and convert them to 178--with-4in6 Check for IPv4 in IPv6 mapped addresses and convert them to
179real (AF_INET) IPv4 addresses. Works around some quirks on Linux. 179real (AF_INET) IPv4 addresses. Works around some quirks on Linux.
180 180
181--with-opensc=DIR
182--with-sectok=DIR allows for OpenSC or sectok smartcard libraries to
183be used with OpenSSH. See 'README.smartcard' for more details.
184
181If you need to pass special options to the compiler or linker, you 185If you need to pass special options to the compiler or linker, you
182can specify these as environment variables before running ./configure. 186can specify these as environment variables before running ./configure.
183For example: 187For example:
@@ -218,4 +222,4 @@ Please refer to the "reporting bugs" section of the webpage at
218http://www.openssh.com/ 222http://www.openssh.com/
219 223
220 224
221$Id: INSTALL,v 1.49 2002/03/07 17:49:40 mouring Exp $ 225$Id: INSTALL,v 1.50 2002/04/05 16:11:46 mouring Exp $
diff --git a/Makefile.in b/Makefile.in
index cae801ef2..32f954096 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
1# $Id: Makefile.in,v 1.200 2002/03/22 02:30:43 mouring Exp $ 1# $Id: Makefile.in,v 1.201 2002/04/05 16:11:46 mouring Exp $
2 2
3prefix=@prefix@ 3prefix=@prefix@
4exec_prefix=@exec_prefix@ 4exec_prefix=@exec_prefix@
@@ -50,7 +50,7 @@ INSTALL_SSH_RAND_HELPER=@INSTALL_SSH_RAND_HELPER@
50 50
51TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} $(SFTP_PROGS) 51TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} $(SFTP_PROGS)
52 52
53LIBSSH_OBJS=atomicio.o authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dh.o dispatch.o fatal.o mac.o hostfile.o key.o kex.o kexdh.o kexgex.o log.o match.o misc.o mpaux.o nchan.o packet.o radix.o rijndael.o entropy.o readpass.o rsa.o scard.o ssh-dss.o ssh-rsa.o tildexpand.o ttymodes.o uidswap.o uuencode.o xmalloc.o monitor_wrap.o monitor_fdpass.o 53LIBSSH_OBJS=atomicio.o authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dh.o dispatch.o fatal.o mac.o hostfile.o key.o kex.o kexdh.o kexgex.o log.o match.o misc.o mpaux.o nchan.o packet.o radix.o rijndael.o entropy.o readpass.o rsa.o scard.o scard-opensc.o ssh-dss.o ssh-rsa.o tildexpand.o ttymodes.o uidswap.o uuencode.o xmalloc.o monitor_wrap.o monitor_fdpass.o
54 54
55SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o sshtty.o readconf.o clientloop.o 55SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o sshtty.o readconf.o clientloop.o
56 56
diff --git a/README.smartcard b/README.smartcard
index 69dca15b5..17bbde721 100644
--- a/README.smartcard
+++ b/README.smartcard
@@ -8,18 +8,22 @@ are still subject to change.
8 8
9To enable this you need to: 9To enable this you need to:
10 10
11(1) install sectok 11(1) install sectok or openSC
12 12
13 Sources are instructions are available from 13 Sources are instructions are available from
14 http://www.citi.umich.edu/projects/smartcard/sectok.html 14 http://www.citi.umich.edu/projects/smartcard/sectok.html
15 15
16 or
17
18 http://www.opensc.org/
19
16(2) enable SMARTCARD support in OpenSSH: 20(2) enable SMARTCARD support in OpenSSH:
17 21
18 $ ./configure --with-smartcard [options] 22 $ ./configure --with-sectok[=/path/to/libsectok] [options]
19 23
20 You can also specify a path to libsectok: 24 or
21 25
22 $ ./configure --with-smartcard=/path/to/libsectok [options] 26 $ ./configure --with-opensc[=/path/to/opensc] [options]
23 27
24(3) load the Java Cardlet to the Cyberflex card: 28(3) load the Java Cardlet to the Cyberflex card:
25 29
diff --git a/acconfig.h b/acconfig.h
index cbdbde216..67afad9aa 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -1,4 +1,4 @@
1/* $Id: acconfig.h,v 1.124 2002/03/22 18:19:54 stevesk Exp $ */ 1/* $Id: acconfig.h,v 1.125 2002/04/05 16:11:46 mouring Exp $ */
2 2
3#ifndef _CONFIG_H 3#ifndef _CONFIG_H
4#define _CONFIG_H 4#define _CONFIG_H
@@ -329,6 +329,12 @@
329/* Define if you want smartcard support */ 329/* Define if you want smartcard support */
330#undef SMARTCARD 330#undef SMARTCARD
331 331
332/* Define if you want smartcard support using sectok */
333#undef USE_SECTOK
334
335/* Define if you want smartcard support using OpenSC */
336#undef USE_OPENSC
337
332/* Define if you want to use OpenSSL's internally seeded PRNG only */ 338/* Define if you want to use OpenSSL's internally seeded PRNG only */
333#undef OPENSSL_PRNG_ONLY 339#undef OPENSSL_PRNG_ONLY
334 340
diff --git a/configure.ac b/configure.ac
index 09607b07d..6bd29254e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
1# $Id: configure.ac,v 1.30 2002/03/31 19:23:07 tim Exp $ 1# $Id: configure.ac,v 1.31 2002/04/05 16:11:46 mouring Exp $
2 2
3AC_INIT 3AC_INIT
4AC_CONFIG_SRCDIR([ssh.c]) 4AC_CONFIG_SRCDIR([ssh.c])
@@ -1667,11 +1667,11 @@ if test "x$ac_cv_libc_defines_sys_nerr" = "xyes" ; then
1667 AC_DEFINE(HAVE_SYS_NERR) 1667 AC_DEFINE(HAVE_SYS_NERR)
1668fi 1668fi
1669 1669
1670
1671# Check whether user wants Kerberos support
1672SCARD_MSG="no" 1670SCARD_MSG="no"
1673AC_ARG_WITH(smartcard, 1671
1674 [ --with-smartcard Enable smartcard support], 1672# Check whether user wants sectok support
1673AC_ARG_WITH(sectok,
1674 [ --with-sectok Enable smartcard support using libsectok],
1675 [ 1675 [
1676 if test "x$withval" != "xno" ; then 1676 if test "x$withval" != "xno" ; then
1677 if test "x$withval" != "xyes" ; then 1677 if test "x$withval" != "xyes" ; then
@@ -1693,7 +1693,38 @@ AC_ARG_WITH(smartcard,
1693 AC_MSG_ERROR(Can't find libsectok) 1693 AC_MSG_ERROR(Can't find libsectok)
1694 fi 1694 fi
1695 AC_DEFINE(SMARTCARD) 1695 AC_DEFINE(SMARTCARD)
1696 SCARD_MSG="yes" 1696 AC_DEFINE(USE_SECTOK)
1697 SCARD_MSG="yes, using sectok"
1698 fi
1699 ]
1700)
1701
1702# Check whether user wants OpenSC support
1703AC_ARG_WITH(opensc,
1704 [ --with-opensc Enable smartcard support using OpenSC],
1705 [
1706 if test "x$withval" != "xno" ; then
1707 if test "x$withval" != "xyes" ; then
1708 CPPFLAGS="$CPPFLAGS -I${withval}"
1709 LDFLAGS="$LDFLAGS -L${withval}"
1710 if test ! -z "$need_dash_r" ; then
1711 LDFLAGS="$LDFLAGS -R${withval}"
1712 fi
1713 if test ! -z "$blibpath" ; then
1714 blibpath="$blibpath:${withval}"
1715 fi
1716 fi
1717 AC_CHECK_HEADERS(opensc-pkcs15.h)
1718 if test "$ac_cv_header_opensc_pkcs15_h" != yes; then
1719 AC_MSG_ERROR(Can't find opensc-pkcs15.h)
1720 fi
1721 AC_CHECK_LIB(opensc, sc_pkcs15_bind)
1722 if test "$ac_cv_lib_opensc_sc_pkcs15_bind" != yes; then
1723 AC_MSG_ERROR(Can't find libopensc)
1724 fi
1725 AC_DEFINE(SMARTCARD)
1726 AC_DEFINE(USE_OPENSC)
1727 SCARD_MSG="yes, using OpenSC"
1697 fi 1728 fi
1698 ] 1729 ]
1699) 1730)
diff --git a/scard-opensc.c b/scard-opensc.c
new file mode 100644
index 000000000..2a18bebd6
--- /dev/null
+++ b/scard-opensc.c
@@ -0,0 +1,462 @@
1/*
2 * Copyright (c) 2002 Juha Yrjölä. All rights reserved.
3 * Copyright (c) 2001 Markus Friedl.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "includes.h"
27#if defined(SMARTCARD) && defined(USE_OPENSC)
28
29#include <openssl/evp.h>
30#include <openssl/x509.h>
31
32#include <opensc.h>
33#include <opensc-pkcs15.h>
34
35#include "key.h"
36#include "log.h"
37#include "xmalloc.h"
38#include "readpass.h"
39#include "scard.h"
40
41#if OPENSSL_VERSION_NUMBER >= 0x00907000L
42#define USE_ENGINE
43#define RSA_get_default_method RSA_get_default_openssl_method
44#else
45#endif
46
47#ifdef USE_ENGINE
48#include <openssl/engine.h>
49#define sc_get_rsa sc_get_engine
50#else
51#define sc_get_rsa sc_get_rsa_method
52#endif
53
54static int sc_reader_id;
55static sc_context_t *ctx = NULL;
56static sc_card_t *card = NULL;
57static sc_pkcs15_card_t *p15card = NULL;
58
59static char *sc_pin = NULL;
60
61struct sc_priv_data
62{
63 struct sc_pkcs15_id cert_id;
64 int ref_count;
65};
66
67void
68sc_close(void)
69{
70 if (p15card) {
71 sc_pkcs15_unbind(p15card);
72 p15card = NULL;
73 }
74 if (card) {
75 sc_disconnect_card(card, 0);
76 card = NULL;
77 }
78 if (ctx) {
79 sc_release_context(ctx);
80 ctx = NULL;
81 }
82}
83
84static int
85sc_init(void)
86{
87 int r;
88
89 r = sc_establish_context(&ctx, "openssh");
90 if (r)
91 goto err;
92 r = sc_connect_card(ctx->reader[sc_reader_id], 0, &card);
93 if (r)
94 goto err;
95 r = sc_pkcs15_bind(card, &p15card);
96 if (r)
97 goto err;
98 return 0;
99err:
100 sc_close();
101 return r;
102}
103
104/* private key operations */
105
106static int
107sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out)
108{
109 int r;
110 struct sc_priv_data *priv;
111 struct sc_pkcs15_object *key_obj;
112 struct sc_pkcs15_prkey_info *key;
113 struct sc_pkcs15_object *pin_obj;
114 struct sc_pkcs15_pin_info *pin;
115
116 priv = (struct sc_priv_data *) RSA_get_app_data(rsa);
117 if (priv == NULL)
118 return -1;
119 if (p15card == NULL) {
120 sc_close();
121 r = sc_init();
122 if (r) {
123 error("SmartCard init failed: %s", sc_strerror(r));
124 goto err;
125 }
126 }
127 r = sc_pkcs15_find_prkey_by_id(p15card, &priv->cert_id, &key_obj);
128 if (r) {
129 error("Unable to find private key from SmartCard: %s",
130 sc_strerror(r));
131 goto err;
132 }
133 key = key_obj->data;
134 r = sc_pkcs15_find_pin_by_auth_id(p15card, &key_obj->auth_id,
135 &pin_obj);
136 if (r) {
137 error("Unable to find PIN object from SmartCard: %s",
138 sc_strerror(r));
139 goto err;
140 }
141 pin = pin_obj->data;
142 r = sc_lock(card);
143 if (r) {
144 error("Unable to lock smartcard: %s", sc_strerror(r));
145 goto err;
146 }
147 if (sc_pin != NULL) {
148 r = sc_pkcs15_verify_pin(p15card, pin, sc_pin,
149 strlen(sc_pin));
150 if (r) {
151 sc_unlock(card);
152 error("PIN code verification failed: %s",
153 sc_strerror(r));
154 goto err;
155 }
156 }
157 *key_obj_out = key_obj;
158 return 0;
159err:
160 sc_close();
161 return -1;
162}
163
164static int
165sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
166 int padding)
167{
168 struct sc_pkcs15_object *key_obj;
169 int r;
170
171 if (padding != RSA_PKCS1_PADDING)
172 return -1;
173 r = sc_prkey_op_init(rsa, &key_obj);
174 if (r)
175 return -1;
176 r = sc_pkcs15_decipher(p15card, key_obj, from, flen, to, flen);
177 sc_unlock(card);
178 if (r < 0) {
179 error("sc_pkcs15_decipher() failed: %s", sc_strerror(r));
180 goto err;
181 }
182 return r;
183err:
184 sc_close();
185 return -1;
186}
187
188static int
189sc_sign(int type, u_char *m, unsigned int m_len,
190 unsigned char *sigret, unsigned int *siglen, RSA *rsa)
191{
192 struct sc_pkcs15_object *key_obj;
193 int r;
194 unsigned long flags = 0;
195
196 r = sc_prkey_op_init(rsa, &key_obj);
197 if (r)
198 return -1;
199 /* FIXME: length of sigret correct? */
200 /* FIXME: check 'type' and modify flags accordingly */
201 flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA1;
202 r = sc_pkcs15_compute_signature(p15card, key_obj, flags,
203 m, m_len, sigret, RSA_size(rsa));
204 sc_unlock(card);
205 if (r < 0) {
206 error("sc_pkcs15_compute_signature() failed: %s",
207 sc_strerror(r));
208 goto err;
209 }
210 *siglen = r;
211 return 1;
212err:
213 sc_close();
214 return 0;
215}
216
217static int
218sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa,
219 int padding)
220{
221 error("Private key encryption not supported");
222 return -1;
223}
224
225/* called on free */
226
227static int (*orig_finish)(RSA *rsa) = NULL;
228
229static int
230sc_finish(RSA *rsa)
231{
232 struct sc_priv_data *priv;
233
234 priv = RSA_get_app_data(rsa);
235 priv->ref_count--;
236 if (priv->ref_count == 0) {
237 free(priv);
238 sc_close();
239 }
240 if (orig_finish)
241 orig_finish(rsa);
242 return 1;
243}
244
245/* engine for overloading private key operations */
246
247static RSA_METHOD *
248sc_get_rsa_method(void)
249{
250 static RSA_METHOD smart_rsa;
251 const RSA_METHOD *def = RSA_get_default_method();
252
253 /* use the OpenSSL version */
254 memcpy(&smart_rsa, def, sizeof(smart_rsa));
255
256 smart_rsa.name = "opensc";
257
258 /* overload */
259 smart_rsa.rsa_priv_enc = sc_private_encrypt;
260 smart_rsa.rsa_priv_dec = sc_private_decrypt;
261 smart_rsa.rsa_sign = sc_sign;
262
263 /* save original */
264 orig_finish = def->finish;
265 smart_rsa.finish = sc_finish;
266
267 return &smart_rsa;
268}
269
270#ifdef USE_ENGINE
271static ENGINE *
272sc_get_engine(void)
273{
274 static ENGINE *smart_engine = NULL;
275
276 if ((smart_engine = ENGINE_new()) == NULL)
277 fatal("ENGINE_new failed");
278
279 ENGINE_set_id(smart_engine, "opensc");
280 ENGINE_set_name(smart_engine, "OpenSC");
281
282 ENGINE_set_RSA(smart_engine, sc_get_rsa_method());
283 ENGINE_set_DSA(smart_engine, DSA_get_default_openssl_method());
284 ENGINE_set_DH(smart_engine, DH_get_default_openssl_method());
285 ENGINE_set_RAND(smart_engine, RAND_SSLeay());
286 ENGINE_set_BN_mod_exp(smart_engine, BN_mod_exp);
287
288 return smart_engine;
289}
290#endif
291
292static void
293convert_rsa_to_rsa1(Key * in, Key * out)
294{
295 struct sc_priv_data *priv;
296
297 out->rsa->flags = in->rsa->flags;
298 out->flags = in->flags;
299 RSA_set_method(out->rsa, RSA_get_method(in->rsa));
300 BN_copy(out->rsa->n, in->rsa->n);
301 BN_copy(out->rsa->e, in->rsa->e);
302 priv = RSA_get_app_data(in->rsa);
303 priv->ref_count++;
304 RSA_set_app_data(out->rsa, priv);
305 return;
306}
307
308static int
309sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj)
310{
311 int r;
312 sc_pkcs15_cert_t *cert = NULL;
313 struct sc_priv_data *priv = NULL;
314 sc_pkcs15_cert_info_t *cinfo = cert_obj->data;
315
316 X509 *x509 = NULL;
317 EVP_PKEY *pubkey = NULL;
318 u8 *p;
319 char *tmp;
320
321 debug("sc_read_pubkey() with cert id %02X", cinfo->id.value[0]);
322 r = sc_pkcs15_read_certificate(p15card, cinfo, &cert);
323 if (r) {
324 log("Certificate read failed: %s", sc_strerror(r));
325 goto err;
326 }
327 x509 = X509_new();
328 if (x509 == NULL) {
329 r = -1;
330 goto err;
331 }
332 p = cert->data;
333 if (!d2i_X509(&x509, &p, cert->data_len)) {
334 log("Unable to parse X.509 certificate");
335 r = -1;
336 goto err;
337 }
338 sc_pkcs15_free_certificate(cert);
339 cert = NULL;
340 pubkey = X509_get_pubkey(x509);
341 X509_free(x509);
342 x509 = NULL;
343 if (pubkey->type != EVP_PKEY_RSA) {
344 log("Public key is of unknown type");
345 r = -1;
346 goto err;
347 }
348 k->rsa = EVP_PKEY_get1_RSA(pubkey);
349 EVP_PKEY_free(pubkey);
350
351 k->rsa->flags |= RSA_FLAG_SIGN_VER;
352 RSA_set_method(k->rsa, sc_get_rsa_method());
353 priv = xmalloc(sizeof(struct sc_priv_data));
354 priv->cert_id = cinfo->id;
355 priv->ref_count = 1;
356 RSA_set_app_data(k->rsa, priv);
357
358 k->flags = KEY_FLAG_EXT;
359 tmp = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX);
360 debug("fingerprint %d %s", key_size(k), tmp);
361 xfree(tmp);
362
363 return 0;
364err:
365 if (cert)
366 sc_pkcs15_free_certificate(cert);
367 if (pubkey)
368 EVP_PKEY_free(pubkey);
369 if (x509)
370 X509_free(x509);
371 return r;
372}
373
374Key **
375sc_get_keys(const char *id, const char *pin)
376{
377 Key *k, **keys;
378 int i, r, real_count = 0, key_count;
379 sc_pkcs15_id_t cert_id;
380 sc_pkcs15_object_t *certs[32];
381 char *buf = xstrdup(id), *p;
382
383 debug("sc_get_keys called: id = %s", id);
384
385 if (sc_pin != NULL)
386 xfree(sc_pin);
387 sc_pin = (pin == NULL) ? NULL : xstrdup(pin);
388
389 cert_id.len = 0;
390 if ((p = strchr(buf, ':')) != NULL) {
391 *p = 0;
392 p++;
393 sc_pkcs15_hex_string_to_id(p, &cert_id);
394 }
395 r = sscanf(buf, "%d", &sc_reader_id);
396 xfree(buf);
397 if (r != 1)
398 goto err;
399 if (p15card == NULL) {
400 sc_close();
401 r = sc_init();
402 if (r) {
403 error("Smartcard init failed: %s", sc_strerror(r));
404 goto err;
405 }
406 }
407 if (cert_id.len) {
408 r = sc_pkcs15_find_cert_by_id(p15card, &cert_id, &certs[0]);
409 if (r < 0)
410 goto err;
411 key_count = 1;
412 } else {
413 r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509,
414 certs, 32);
415 if (r == 0) {
416 log("No certificates found on smartcard");
417 r = -1;
418 goto err;
419 } else if (r < 0) {
420 error("Certificate enumeration failed: %s",
421 sc_strerror(r));
422 goto err;
423 }
424 key_count = r;
425 }
426 /* FIXME: only keep entries with a corresponding private key */
427 keys = xmalloc(sizeof(Key *) * (key_count*2+1));
428 for (i = 0; i < key_count; i++) {
429 k = key_new(KEY_RSA);
430 if (k == NULL)
431 break;
432 r = sc_read_pubkey(k, certs[i]);
433 if (r) {
434 error("sc_read_pubkey failed: %s", sc_strerror(r));
435 key_free(k);
436 continue;
437 }
438 keys[real_count] = k;
439 real_count++;
440 k = key_new(KEY_RSA1);
441 if (k == NULL)
442 break;
443 convert_rsa_to_rsa1(keys[real_count-1], k);
444 keys[real_count] = k;
445 real_count++;
446 }
447 keys[real_count] = NULL;
448
449 return keys;
450err:
451 sc_close();
452 return NULL;
453}
454
455int
456sc_put_key(Key *prv, const char *id)
457{
458 error("key uploading not yet supported");
459 return -1;
460}
461
462#endif /* SMARTCARD */
diff --git a/scard.c b/scard.c
index de53f9d01..db0cc4a80 100644
--- a/scard.c
+++ b/scard.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26#ifdef SMARTCARD 26#if defined(SMARTCARD) && defined(USE_SECTOK)
27RCSID("$OpenBSD: scard.c,v 1.25 2002/03/26 18:46:59 rees Exp $"); 27RCSID("$OpenBSD: scard.c,v 1.25 2002/03/26 18:46:59 rees Exp $");
28 28
29#include <openssl/evp.h> 29#include <openssl/evp.h>
@@ -554,4 +554,4 @@ done:
554 sectok_close(fd); 554 sectok_close(fd);
555 return (status); 555 return (status);
556} 556}
557#endif /* SMARTCARD */ 557#endif /* SMARTCARD && USE_SECTOK */