Merge from vendor branch ZLIB:
[dragonfly.git] / crypto / openssh-3.9p1 / scard.c
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.29 2004/05/08 00:21:31 djm 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 "misc.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 */