~ubuntu-branches/ubuntu/edgy/openssh/edgy

« back to all changes in this revision

Viewing changes to scard.c

  • Committer: Bazaar Package Importer
  • Author(s): Noah Meyerhans
  • Date: 2006-10-31 17:53:38 UTC
  • Revision ID: james.westby@ubuntu.com-20061031175338-kh299ada2qc2kzlb
Tags: upstream-3.8.1p1
ImportĀ upstreamĀ versionĀ 3.8.1p1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2001 Markus Friedl.  All rights reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions
 
6
 * are met:
 
7
 * 1. Redistributions of source code must retain the above copyright
 
8
 *    notice, this list of conditions and the following disclaimer.
 
9
 * 2. Redistributions in binary form must reproduce the above copyright
 
10
 *    notice, this list of conditions and the following disclaimer in the
 
11
 *    documentation and/or other materials provided with the distribution.
 
12
 *
 
13
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 
14
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
15
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 
16
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 
17
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
18
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
19
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
20
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
21
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
22
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
23
 */
 
24
 
 
25
#include "includes.h"
 
26
#if defined(SMARTCARD) && defined(USE_SECTOK)
 
27
RCSID("$OpenBSD: scard.c,v 1.28 2003/06/12 19:12:02 markus Exp $");
 
28
 
 
29
#include <openssl/evp.h>
 
30
#include <sectok.h>
 
31
 
 
32
#include "key.h"
 
33
#include "log.h"
 
34
#include "xmalloc.h"
 
35
#include "readpass.h"
 
36
#include "scard.h"
 
37
 
 
38
#if OPENSSL_VERSION_NUMBER < 0x00907000L
 
39
#define USE_ENGINE
 
40
#define RSA_get_default_method RSA_get_default_openssl_method
 
41
#else
 
42
#endif
 
43
 
 
44
#ifdef USE_ENGINE
 
45
#include <openssl/engine.h>
 
46
#define sc_get_rsa sc_get_engine
 
47
#else
 
48
#define sc_get_rsa sc_get_rsa_method
 
49
#endif
 
50
 
 
51
#define CLA_SSH 0x05
 
52
#define INS_DECRYPT 0x10
 
53
#define INS_GET_KEYLENGTH 0x20
 
54
#define INS_GET_PUBKEY 0x30
 
55
#define INS_GET_RESPONSE 0xc0
 
56
 
 
57
#define MAX_BUF_SIZE 256
 
58
 
 
59
u_char DEFAUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63};
 
60
 
 
61
static int sc_fd = -1;
 
62
static char *sc_reader_id = NULL;
 
63
static char *sc_pin = NULL;
 
64
static int cla = 0x00;  /* class */
 
65
 
 
66
static void sc_mk_digest(const char *pin, u_char *digest);
 
67
static int get_AUT0(u_char *aut0);
 
68
static int try_AUT0(void);
 
69
 
 
70
/* interface to libsectok */
 
71
 
 
72
static int
 
73
sc_open(void)
 
74
{
 
75
        int sw;
 
76
 
 
77
        if (sc_fd >= 0)
 
78
                return sc_fd;
 
79
 
 
80
        sc_fd = sectok_friendly_open(sc_reader_id, STONOWAIT, &sw);
 
81
        if (sc_fd < 0) {
 
82
                error("sectok_open failed: %s", sectok_get_sw(sw));
 
83
                return SCARD_ERROR_FAIL;
 
84
        }
 
85
        if (! sectok_cardpresent(sc_fd)) {
 
86
                debug("smartcard in reader %s not present, skipping",
 
87
                    sc_reader_id);
 
88
                sc_close();
 
89
                return SCARD_ERROR_NOCARD;
 
90
        }
 
91
        if (sectok_reset(sc_fd, 0, NULL, &sw) <= 0) {
 
92
                error("sectok_reset failed: %s", sectok_get_sw(sw));
 
93
                sc_fd = -1;
 
94
                return SCARD_ERROR_FAIL;
 
95
        }
 
96
        if ((cla = cyberflex_inq_class(sc_fd)) < 0)
 
97
                cla = 0;
 
98
 
 
99
        debug("sc_open ok %d", sc_fd);
 
100
        return sc_fd;
 
101
}
 
102
 
 
103
static int
 
104
sc_enable_applet(void)
 
105
{
 
106
        static u_char aid[] = {0xfc, 0x53, 0x73, 0x68, 0x2e, 0x62, 0x69, 0x6e};
 
107
        int sw = 0;
 
108
 
 
109
        /* select applet id */
 
110
        sectok_apdu(sc_fd, cla, 0xa4, 0x04, 0, sizeof aid, aid, 0, NULL, &sw);
 
111
        if (!sectok_swOK(sw)) {
 
112
                error("sectok_apdu failed: %s", sectok_get_sw(sw));
 
113
                sc_close();
 
114
                return -1;
 
115
        }
 
116
        return 0;
 
117
}
 
118
 
 
119
static int
 
120
sc_init(void)
 
121
{
 
122
        int status;
 
123
 
 
124
        status = sc_open();
 
125
        if (status == SCARD_ERROR_NOCARD) {
 
126
                return SCARD_ERROR_NOCARD;
 
127
        }
 
128
        if (status < 0 ) {
 
129
                error("sc_open failed");
 
130
                return status;
 
131
        }
 
132
        if (sc_enable_applet() < 0) {
 
133
                error("sc_enable_applet failed");
 
134
                return SCARD_ERROR_APPLET;
 
135
        }
 
136
        return 0;
 
137
}
 
138
 
 
139
static int
 
140
sc_read_pubkey(Key * k)
 
141
{
 
142
        u_char buf[2], *n;
 
143
        char *p;
 
144
        int len, sw, status = -1;
 
145
 
 
146
        len = sw = 0;
 
147
        n = NULL;
 
148
 
 
149
        if (sc_fd < 0) {
 
150
                if (sc_init() < 0)
 
151
                        goto err;
 
152
        }
 
153
 
 
154
        /* get key size */
 
155
        sectok_apdu(sc_fd, CLA_SSH, INS_GET_KEYLENGTH, 0, 0, 0, NULL,
 
156
            sizeof(buf), buf, &sw);
 
157
        if (!sectok_swOK(sw)) {
 
158
                error("could not obtain key length: %s", sectok_get_sw(sw));
 
159
                goto err;
 
160
        }
 
161
        len = (buf[0] << 8) | buf[1];
 
162
        len /= 8;
 
163
        debug("INS_GET_KEYLENGTH: len %d sw %s", len, sectok_get_sw(sw));
 
164
 
 
165
        n = xmalloc(len);
 
166
        /* get n */
 
167
        sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw);
 
168
 
 
169
        if (sw == 0x6982) {
 
170
                if (try_AUT0() < 0)
 
171
                        goto err;
 
172
                sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw);
 
173
        }
 
174
        if (!sectok_swOK(sw)) {
 
175
                error("could not obtain public key: %s", sectok_get_sw(sw));
 
176
                goto err;
 
177
        }
 
178
 
 
179
        debug("INS_GET_KEYLENGTH: sw %s", sectok_get_sw(sw));
 
180
 
 
181
        if (BN_bin2bn(n, len, k->rsa->n) == NULL) {
 
182
                error("c_read_pubkey: BN_bin2bn failed");
 
183
                goto err;
 
184
        }
 
185
 
 
186
        /* currently the java applet just stores 'n' */
 
187
        if (!BN_set_word(k->rsa->e, 35)) {
 
188
                error("c_read_pubkey: BN_set_word(e, 35) failed");
 
189
                goto err;
 
190
        }
 
191
 
 
192
        status = 0;
 
193
        p = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX);
 
194
        debug("fingerprint %u %s", key_size(k), p);
 
195
        xfree(p);
 
196
 
 
197
err:
 
198
        if (n != NULL)
 
199
                xfree(n);
 
200
        sc_close();
 
201
        return status;
 
202
}
 
203
 
 
204
/* private key operations */
 
205
 
 
206
static int
 
207
sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
 
208
    int padding)
 
209
{
 
210
        u_char *padded = NULL;
 
211
        int sw, len, olen, status = -1;
 
212
 
 
213
        debug("sc_private_decrypt called");
 
214
 
 
215
        olen = len = sw = 0;
 
216
        if (sc_fd < 0) {
 
217
                status = sc_init();
 
218
                if (status < 0 )
 
219
                        goto err;
 
220
        }
 
221
        if (padding != RSA_PKCS1_PADDING)
 
222
                goto err;
 
223
 
 
224
        len = BN_num_bytes(rsa->n);
 
225
        padded = xmalloc(len);
 
226
 
 
227
        sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
 
228
 
 
229
        if (sw == 0x6982) {
 
230
                if (try_AUT0() < 0)
 
231
                        goto err;
 
232
                sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
 
233
        }
 
234
        if (!sectok_swOK(sw)) {
 
235
                error("sc_private_decrypt: INS_DECRYPT failed: %s",
 
236
                    sectok_get_sw(sw));
 
237
                goto err;
 
238
        }
 
239
        olen = RSA_padding_check_PKCS1_type_2(to, len, padded + 1, len - 1,
 
240
            len);
 
241
err:
 
242
        if (padded)
 
243
                xfree(padded);
 
244
        sc_close();
 
245
        return (olen >= 0 ? olen : status);
 
246
}
 
247
 
 
248
static int
 
249
sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa,
 
250
    int padding)
 
251
{
 
252
        u_char *padded = NULL;
 
253
        int sw, len, status = -1;
 
254
 
 
255
        len = sw = 0;
 
256
        if (sc_fd < 0) {
 
257
                status = sc_init();
 
258
                if (status < 0 )
 
259
                        goto err;
 
260
        }
 
261
        if (padding != RSA_PKCS1_PADDING)
 
262
                goto err;
 
263
 
 
264
        debug("sc_private_encrypt called");
 
265
        len = BN_num_bytes(rsa->n);
 
266
        padded = xmalloc(len);
 
267
 
 
268
        if (RSA_padding_add_PKCS1_type_1(padded, len, (u_char *)from, flen) <= 0) {
 
269
                error("RSA_padding_add_PKCS1_type_1 failed");
 
270
                goto err;
 
271
        }
 
272
        sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw);
 
273
        if (sw == 0x6982) {
 
274
                if (try_AUT0() < 0)
 
275
                        goto err;
 
276
                sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw);
 
277
        }
 
278
        if (!sectok_swOK(sw)) {
 
279
                error("sc_private_encrypt: INS_DECRYPT failed: %s",
 
280
                    sectok_get_sw(sw));
 
281
                goto err;
 
282
        }
 
283
err:
 
284
        if (padded)
 
285
                xfree(padded);
 
286
        sc_close();
 
287
        return (len >= 0 ? len : status);
 
288
}
 
289
 
 
290
/* called on free */
 
291
 
 
292
static int (*orig_finish)(RSA *rsa) = NULL;
 
293
 
 
294
static int
 
295
sc_finish(RSA *rsa)
 
296
{
 
297
        if (orig_finish)
 
298
                orig_finish(rsa);
 
299
        sc_close();
 
300
        return 1;
 
301
}
 
302
 
 
303
/* engine for overloading private key operations */
 
304
 
 
305
static RSA_METHOD *
 
306
sc_get_rsa_method(void)
 
307
{
 
308
        static RSA_METHOD smart_rsa;
 
309
        const RSA_METHOD *def = RSA_get_default_method();
 
310
 
 
311
        /* use the OpenSSL version */
 
312
        memcpy(&smart_rsa, def, sizeof(smart_rsa));
 
313
 
 
314
        smart_rsa.name          = "sectok";
 
315
 
 
316
        /* overload */
 
317
        smart_rsa.rsa_priv_enc  = sc_private_encrypt;
 
318
        smart_rsa.rsa_priv_dec  = sc_private_decrypt;
 
319
 
 
320
        /* save original */
 
321
        orig_finish             = def->finish;
 
322
        smart_rsa.finish        = sc_finish;
 
323
 
 
324
        return &smart_rsa;
 
325
}
 
326
 
 
327
#ifdef USE_ENGINE
 
328
static ENGINE *
 
329
sc_get_engine(void)
 
330
{
 
331
        static ENGINE *smart_engine = NULL;
 
332
 
 
333
        if ((smart_engine = ENGINE_new()) == NULL)
 
334
                fatal("ENGINE_new failed");
 
335
 
 
336
        ENGINE_set_id(smart_engine, "sectok");
 
337
        ENGINE_set_name(smart_engine, "libsectok");
 
338
 
 
339
        ENGINE_set_RSA(smart_engine, sc_get_rsa_method());
 
340
        ENGINE_set_DSA(smart_engine, DSA_get_default_openssl_method());
 
341
        ENGINE_set_DH(smart_engine, DH_get_default_openssl_method());
 
342
        ENGINE_set_RAND(smart_engine, RAND_SSLeay());
 
343
        ENGINE_set_BN_mod_exp(smart_engine, BN_mod_exp);
 
344
 
 
345
        return smart_engine;
 
346
}
 
347
#endif
 
348
 
 
349
void
 
350
sc_close(void)
 
351
{
 
352
        if (sc_fd >= 0) {
 
353
                sectok_close(sc_fd);
 
354
                sc_fd = -1;
 
355
        }
 
356
}
 
357
 
 
358
Key **
 
359
sc_get_keys(const char *id, const char *pin)
 
360
{
 
361
        Key *k, *n, **keys;
 
362
        int status, nkeys = 2;
 
363
 
 
364
        if (sc_reader_id != NULL)
 
365
                xfree(sc_reader_id);
 
366
        sc_reader_id = xstrdup(id);
 
367
 
 
368
        if (sc_pin != NULL)
 
369
                xfree(sc_pin);
 
370
        sc_pin = (pin == NULL) ? NULL : xstrdup(pin);
 
371
 
 
372
        k = key_new(KEY_RSA);
 
373
        if (k == NULL) {
 
374
                return NULL;
 
375
        }
 
376
        status = sc_read_pubkey(k);
 
377
        if (status == SCARD_ERROR_NOCARD) {
 
378
                key_free(k);
 
379
                return NULL;
 
380
        }
 
381
        if (status < 0 ) {
 
382
                error("sc_read_pubkey failed");
 
383
                key_free(k);
 
384
                return NULL;
 
385
        }
 
386
        keys = xmalloc((nkeys+1) * sizeof(Key *));
 
387
 
 
388
        n = key_new(KEY_RSA1);
 
389
        BN_copy(n->rsa->n, k->rsa->n);
 
390
        BN_copy(n->rsa->e, k->rsa->e);
 
391
        RSA_set_method(n->rsa, sc_get_rsa());
 
392
        n->flags |= KEY_FLAG_EXT;
 
393
        keys[0] = n;
 
394
 
 
395
        n = key_new(KEY_RSA);
 
396
        BN_copy(n->rsa->n, k->rsa->n);
 
397
        BN_copy(n->rsa->e, k->rsa->e);
 
398
        RSA_set_method(n->rsa, sc_get_rsa());
 
399
        n->flags |= KEY_FLAG_EXT;
 
400
        keys[1] = n;
 
401
 
 
402
        keys[2] = NULL;
 
403
 
 
404
        key_free(k);
 
405
        return keys;
 
406
}
 
407
 
 
408
#define NUM_RSA_KEY_ELEMENTS 5+1
 
409
#define COPY_RSA_KEY(x, i) \
 
410
        do { \
 
411
                len = BN_num_bytes(prv->rsa->x); \
 
412
                elements[i] = xmalloc(len); \
 
413
                debug("#bytes %d", len); \
 
414
                if (BN_bn2bin(prv->rsa->x, elements[i]) < 0) \
 
415
                        goto done; \
 
416
        } while (0)
 
417
 
 
418
static void
 
419
sc_mk_digest(const char *pin, u_char *digest)
 
420
{
 
421
        const EVP_MD *evp_md = EVP_sha1();
 
422
        EVP_MD_CTX md;
 
423
 
 
424
        EVP_DigestInit(&md, evp_md);
 
425
        EVP_DigestUpdate(&md, pin, strlen(pin));
 
426
        EVP_DigestFinal(&md, digest, NULL);
 
427
}
 
428
 
 
429
static int
 
430
get_AUT0(u_char *aut0)
 
431
{
 
432
        char *pass;
 
433
 
 
434
        pass = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN);
 
435
        if (pass == NULL)
 
436
                return -1;
 
437
        if (!strcmp(pass, "-")) {
 
438
                memcpy(aut0, DEFAUT0, sizeof DEFAUT0);
 
439
                return 0;
 
440
        }
 
441
        sc_mk_digest(pass, aut0);
 
442
        memset(pass, 0, strlen(pass));
 
443
        xfree(pass);
 
444
        return 0;
 
445
}
 
446
 
 
447
static int
 
448
try_AUT0(void)
 
449
{
 
450
        u_char aut0[EVP_MAX_MD_SIZE];
 
451
 
 
452
        /* permission denied; try PIN if provided */
 
453
        if (sc_pin && strlen(sc_pin) > 0) {
 
454
                sc_mk_digest(sc_pin, aut0);
 
455
                if (cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) {
 
456
                        error("smartcard passphrase incorrect");
 
457
                        return (-1);
 
458
                }
 
459
        } else {
 
460
                /* try default AUT0 key */
 
461
                if (cyberflex_verify_AUT0(sc_fd, cla, DEFAUT0, 8) < 0) {
 
462
                        /* default AUT0 key failed; prompt for passphrase */
 
463
                        if (get_AUT0(aut0) < 0 ||
 
464
                            cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) {
 
465
                                error("smartcard passphrase incorrect");
 
466
                                return (-1);
 
467
                        }
 
468
                }
 
469
        }
 
470
        return (0);
 
471
}
 
472
 
 
473
int
 
474
sc_put_key(Key *prv, const char *id)
 
475
{
 
476
        u_char *elements[NUM_RSA_KEY_ELEMENTS];
 
477
        u_char key_fid[2];
 
478
        u_char AUT0[EVP_MAX_MD_SIZE];
 
479
        int len, status = -1, i, fd = -1, ret;
 
480
        int sw = 0, cla = 0x00;
 
481
 
 
482
        for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
 
483
                elements[i] = NULL;
 
484
 
 
485
        COPY_RSA_KEY(q, 0);
 
486
        COPY_RSA_KEY(p, 1);
 
487
        COPY_RSA_KEY(iqmp, 2);
 
488
        COPY_RSA_KEY(dmq1, 3);
 
489
        COPY_RSA_KEY(dmp1, 4);
 
490
        COPY_RSA_KEY(n, 5);
 
491
        len = BN_num_bytes(prv->rsa->n);
 
492
        fd = sectok_friendly_open(id, STONOWAIT, &sw);
 
493
        if (fd < 0) {
 
494
                error("sectok_open failed: %s", sectok_get_sw(sw));
 
495
                goto done;
 
496
        }
 
497
        if (! sectok_cardpresent(fd)) {
 
498
                error("smartcard in reader %s not present", id);
 
499
                goto done;
 
500
        }
 
501
        ret = sectok_reset(fd, 0, NULL, &sw);
 
502
        if (ret <= 0) {
 
503
                error("sectok_reset failed: %s", sectok_get_sw(sw));
 
504
                goto done;
 
505
        }
 
506
        if ((cla = cyberflex_inq_class(fd)) < 0) {
 
507
                error("cyberflex_inq_class failed");
 
508
                goto done;
 
509
        }
 
510
        memcpy(AUT0, DEFAUT0, sizeof(DEFAUT0));
 
511
        if (cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
 
512
                if (get_AUT0(AUT0) < 0 ||
 
513
                    cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
 
514
                        memset(AUT0, 0, sizeof(DEFAUT0));
 
515
                        error("smartcard passphrase incorrect");
 
516
                        goto done;
 
517
                }
 
518
        }
 
519
        memset(AUT0, 0, sizeof(DEFAUT0));
 
520
        key_fid[0] = 0x00;
 
521
        key_fid[1] = 0x12;
 
522
        if (cyberflex_load_rsa_priv(fd, cla, key_fid, 5, 8*len, elements,
 
523
            &sw) < 0) {
 
524
                error("cyberflex_load_rsa_priv failed: %s", sectok_get_sw(sw));
 
525
                goto done;
 
526
        }
 
527
        if (!sectok_swOK(sw))
 
528
                goto done;
 
529
        logit("cyberflex_load_rsa_priv done");
 
530
        key_fid[0] = 0x73;
 
531
        key_fid[1] = 0x68;
 
532
        if (cyberflex_load_rsa_pub(fd, cla, key_fid, len, elements[5],
 
533
            &sw) < 0) {
 
534
                error("cyberflex_load_rsa_pub failed: %s", sectok_get_sw(sw));
 
535
                goto done;
 
536
        }
 
537
        if (!sectok_swOK(sw))
 
538
                goto done;
 
539
        logit("cyberflex_load_rsa_pub done");
 
540
        status = 0;
 
541
 
 
542
done:
 
543
        memset(elements[0], '\0', BN_num_bytes(prv->rsa->q));
 
544
        memset(elements[1], '\0', BN_num_bytes(prv->rsa->p));
 
545
        memset(elements[2], '\0', BN_num_bytes(prv->rsa->iqmp));
 
546
        memset(elements[3], '\0', BN_num_bytes(prv->rsa->dmq1));
 
547
        memset(elements[4], '\0', BN_num_bytes(prv->rsa->dmp1));
 
548
        memset(elements[5], '\0', BN_num_bytes(prv->rsa->n));
 
549
 
 
550
        for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
 
551
                if (elements[i])
 
552
                        xfree(elements[i]);
 
553
        if (fd != -1)
 
554
                sectok_close(fd);
 
555
        return (status);
 
556
}
 
557
 
 
558
char *
 
559
sc_get_key_label(Key *key)
 
560
{
 
561
        return xstrdup("smartcard key");
 
562
}
 
563
 
 
564
#endif /* SMARTCARD && USE_SECTOK */