summaryrefslogtreecommitdiff
path: root/scard.c
diff options
context:
space:
mode:
Diffstat (limited to 'scard.c')
-rw-r--r--scard.c84
1 files changed, 57 insertions, 27 deletions
diff --git a/scard.c b/scard.c
index 9d044acb9..a8ee2fe6d 100644
--- a/scard.c
+++ b/scard.c
@@ -24,7 +24,7 @@
24 24
25#include "includes.h" 25#include "includes.h"
26#ifdef SMARTCARD 26#ifdef SMARTCARD
27RCSID("$OpenBSD: scard.c,v 1.21 2002/03/21 18:08:15 rees Exp $"); 27RCSID("$OpenBSD: scard.c,v 1.22 2002/03/21 21:54:34 rees Exp $");
28 28
29#include <openssl/engine.h> 29#include <openssl/engine.h>
30#include <openssl/evp.h> 30#include <openssl/evp.h>
@@ -33,8 +33,8 @@ RCSID("$OpenBSD: scard.c,v 1.21 2002/03/21 18:08:15 rees Exp $");
33#include "key.h" 33#include "key.h"
34#include "log.h" 34#include "log.h"
35#include "xmalloc.h" 35#include "xmalloc.h"
36#include "scard.h"
37#include "readpass.h" 36#include "readpass.h"
37#include "scard.h"
38 38
39#ifdef OPENSSL_VERSION_NUMBER 39#ifdef OPENSSL_VERSION_NUMBER
40#if OPENSSL_VERSION_NUMBER >= 0x00907000L 40#if OPENSSL_VERSION_NUMBER >= 0x00907000L
@@ -53,10 +53,16 @@ RCSID("$OpenBSD: scard.c,v 1.21 2002/03/21 18:08:15 rees Exp $");
53 53
54#define MAX_BUF_SIZE 256 54#define MAX_BUF_SIZE 256
55 55
56u_char DEFAUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63};
57
56static int sc_fd = -1; 58static int sc_fd = -1;
57static char *sc_reader_id = NULL; 59static char *sc_reader_id = NULL;
60static char *sc_pin = NULL;
58static int cla = 0x00; /* class */ 61static int cla = 0x00; /* class */
59 62
63static void sc_mk_digest(const char *pin, u_char *digest);
64static int get_AUT0(u_char *aut0);
65
60/* interface to libsectok */ 66/* interface to libsectok */
61 67
62static int 68static int
@@ -193,6 +199,7 @@ sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
193 int padding) 199 int padding)
194{ 200{
195 u_char *padded = NULL; 201 u_char *padded = NULL;
202 u_char aut0[EVP_MAX_MD_SIZE];
196 int sw, len, olen, status = -1; 203 int sw, len, olen, status = -1;
197 204
198 debug("sc_private_decrypt called"); 205 debug("sc_private_decrypt called");
@@ -209,17 +216,31 @@ sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
209 len = BN_num_bytes(rsa->n); 216 len = BN_num_bytes(rsa->n);
210 padded = xmalloc(len); 217 padded = xmalloc(len);
211 218
212 sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, (u_char *)from, 219 sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
213 0, NULL, &sw); 220
214 if (!sectok_swOK(sw)) { 221 if (sw == 0x6982) {
215 error("sc_private_decrypt: INS_DECRYPT failed: %s", 222 /* permission denied; try PIN if provided */
216 sectok_get_sw(sw)); 223 if (sc_pin && strlen(sc_pin) > 0) {
217 goto err; 224 sc_mk_digest(sc_pin, aut0);
225 if (cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) {
226 error("smartcard passphrase incorrect");
227 goto err;
228 }
229 } else {
230 /* try default AUT0 key */
231 if (cyberflex_verify_AUT0(sc_fd, cla, DEFAUT0, 8) < 0) {
232 /* default AUT0 key failed; prompt for passphrase */
233 if (get_AUT0(aut0) < 0 ||
234 cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) {
235 error("smartcard passphrase incorrect");
236 goto err;
237 }
238 }
239 }
240 sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
218 } 241 }
219 sectok_apdu(sc_fd, CLA_SSH, INS_GET_RESPONSE, 0, 0, 0, NULL,
220 len, padded, &sw);
221 if (!sectok_swOK(sw)) { 242 if (!sectok_swOK(sw)) {
222 error("sc_private_decrypt: INS_GET_RESPONSE failed: %s", 243 error("sc_private_decrypt: INS_DECRYPT failed: %s",
223 sectok_get_sw(sw)); 244 sectok_get_sw(sw));
224 goto err; 245 goto err;
225 } 246 }
@@ -256,19 +277,12 @@ sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa,
256 error("RSA_padding_add_PKCS1_type_1 failed"); 277 error("RSA_padding_add_PKCS1_type_1 failed");
257 goto err; 278 goto err;
258 } 279 }
259 sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, 0, NULL, &sw); 280 sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw);
260 if (!sectok_swOK(sw)) { 281 if (!sectok_swOK(sw)) {
261 error("sc_private_decrypt: INS_DECRYPT failed: %s", 282 error("sc_private_decrypt: INS_DECRYPT failed: %s",
262 sectok_get_sw(sw)); 283 sectok_get_sw(sw));
263 goto err; 284 goto err;
264 } 285 }
265 sectok_apdu(sc_fd, CLA_SSH, INS_GET_RESPONSE, 0, 0, 0, NULL,
266 len, to, &sw);
267 if (!sectok_swOK(sw)) {
268 error("sc_private_decrypt: INS_GET_RESPONSE failed: %s",
269 sectok_get_sw(sw));
270 goto err;
271 }
272err: 286err:
273 if (padded) 287 if (padded)
274 xfree(padded); 288 xfree(padded);
@@ -340,7 +354,7 @@ sc_close(void)
340} 354}
341 355
342Key * 356Key *
343sc_get_key(const char *id) 357sc_get_key(const char *id, const char *pin)
344{ 358{
345 Key *k; 359 Key *k;
346 int status; 360 int status;
@@ -349,6 +363,10 @@ sc_get_key(const char *id)
349 xfree(sc_reader_id); 363 xfree(sc_reader_id);
350 sc_reader_id = xstrdup(id); 364 sc_reader_id = xstrdup(id);
351 365
366 if (sc_pin != NULL)
367 xfree(sc_pin);
368 sc_pin = (pin == NULL) ? NULL : xstrdup(pin);
369
352 k = key_new(KEY_RSA); 370 k = key_new(KEY_RSA);
353 if (k == NULL) { 371 if (k == NULL) {
354 return NULL; 372 return NULL;
@@ -376,19 +394,30 @@ sc_get_key(const char *id)
376 goto done; \ 394 goto done; \
377 } while (0) 395 } while (0)
378 396
379static int 397static void
380get_AUT0(char *aut0) 398sc_mk_digest(const char *pin, u_char *digest)
381{ 399{
382 const EVP_MD *evp_md = EVP_sha1(); 400 const EVP_MD *evp_md = EVP_sha1();
383 EVP_MD_CTX md; 401 EVP_MD_CTX md;
402
403 EVP_DigestInit(&md, evp_md);
404 EVP_DigestUpdate(&md, pin, strlen(pin));
405 EVP_DigestFinal(&md, digest, NULL);
406}
407
408static int
409get_AUT0(u_char *aut0)
410{
384 char *pass; 411 char *pass;
385 412
386 pass = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN); 413 pass = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN);
387 if (pass == NULL) 414 if (pass == NULL)
388 return -1; 415 return -1;
389 EVP_DigestInit(&md, evp_md); 416 if (!strcmp(pass, "-")) {
390 EVP_DigestUpdate(&md, pass, strlen(pass)); 417 memcpy(aut0, DEFAUT0, sizeof DEFAUT0);
391 EVP_DigestFinal(&md, aut0, NULL); 418 return 0;
419 }
420 sc_mk_digest(pass, aut0);
392 memset(pass, 0, strlen(pass)); 421 memset(pass, 0, strlen(pass));
393 xfree(pass); 422 xfree(pass);
394 return 0; 423 return 0;
@@ -399,7 +428,6 @@ sc_put_key(Key *prv, const char *id)
399{ 428{
400 u_char *elements[NUM_RSA_KEY_ELEMENTS]; 429 u_char *elements[NUM_RSA_KEY_ELEMENTS];
401 u_char key_fid[2]; 430 u_char key_fid[2];
402 u_char DEFAUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63};
403 u_char AUT0[EVP_MAX_MD_SIZE]; 431 u_char AUT0[EVP_MAX_MD_SIZE];
404 int len, status = -1, i, fd = -1, ret; 432 int len, status = -1, i, fd = -1, ret;
405 int sw = 0, cla = 0x00; 433 int sw = 0, cla = 0x00;
@@ -436,10 +464,12 @@ sc_put_key(Key *prv, const char *id)
436 if (cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) { 464 if (cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
437 if (get_AUT0(AUT0) < 0 || 465 if (get_AUT0(AUT0) < 0 ||
438 cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) { 466 cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
439 error("cyberflex_verify_AUT0 failed"); 467 memset(AUT0, 0, sizeof(DEFAUT0));
468 error("smartcard passphrase incorrect");
440 goto done; 469 goto done;
441 } 470 }
442 } 471 }
472 memset(AUT0, 0, sizeof(DEFAUT0));
443 key_fid[0] = 0x00; 473 key_fid[0] = 0x00;
444 key_fid[1] = 0x12; 474 key_fid[1] = 0x12;
445 if (cyberflex_load_rsa_priv(fd, cla, key_fid, 5, 8*len, elements, 475 if (cyberflex_load_rsa_priv(fd, cla, key_fid, 5, 8*len, elements,