diff options
author | Ben Lindstrom <mouring@eviladmin.org> | 2002-03-22 03:47:38 +0000 |
---|---|---|
committer | Ben Lindstrom <mouring@eviladmin.org> | 2002-03-22 03:47:38 +0000 |
commit | 266ec63eb36e2d3154ead355ce67cdee5c9394a3 (patch) | |
tree | 09b82e7682702d238de7b7055936721e6a1c9397 | |
parent | 943481cc774d31f5de75c16efbe8f3394e9470ab (diff) |
- rees@cvs.openbsd.org 2002/03/21 21:54:34
[scard.c scard.h ssh-keygen.c]
Add PIN-protection for secret key.
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | scard.c | 84 | ||||
-rw-r--r-- | scard.h | 4 | ||||
-rw-r--r-- | ssh-keygen.c | 4 |
4 files changed, 65 insertions, 32 deletions
@@ -136,6 +136,9 @@ | |||
136 | - markus@cvs.openbsd.org 2002/03/21 21:23:34 | 136 | - markus@cvs.openbsd.org 2002/03/21 21:23:34 |
137 | [sshd.c] | 137 | [sshd.c] |
138 | add privsep_preauth() and remove 1 goto; ok provos@ | 138 | add privsep_preauth() and remove 1 goto; ok provos@ |
139 | - rees@cvs.openbsd.org 2002/03/21 21:54:34 | ||
140 | [scard.c scard.h ssh-keygen.c] | ||
141 | Add PIN-protection for secret key. | ||
139 | 142 | ||
140 | 20020317 | 143 | 20020317 |
141 | - (tim) [configure.ac] Assume path given with --with-pid-dir=PATH is wanted, | 144 | - (tim) [configure.ac] Assume path given with --with-pid-dir=PATH is wanted, |
@@ -7982,4 +7985,4 @@ | |||
7982 | - Wrote replacements for strlcpy and mkdtemp | 7985 | - Wrote replacements for strlcpy and mkdtemp |
7983 | - Released 1.0pre1 | 7986 | - Released 1.0pre1 |
7984 | 7987 | ||
7985 | $Id: ChangeLog,v 1.1963 2002/03/22 03:43:46 mouring Exp $ | 7988 | $Id: ChangeLog,v 1.1964 2002/03/22 03:47:38 mouring Exp $ |
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | #ifdef SMARTCARD | 26 | #ifdef SMARTCARD |
27 | RCSID("$OpenBSD: scard.c,v 1.21 2002/03/21 18:08:15 rees Exp $"); | 27 | RCSID("$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 | ||
56 | u_char DEFAUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63}; | ||
57 | |||
56 | static int sc_fd = -1; | 58 | static int sc_fd = -1; |
57 | static char *sc_reader_id = NULL; | 59 | static char *sc_reader_id = NULL; |
60 | static char *sc_pin = NULL; | ||
58 | static int cla = 0x00; /* class */ | 61 | static int cla = 0x00; /* class */ |
59 | 62 | ||
63 | static void sc_mk_digest(const char *pin, u_char *digest); | ||
64 | static int get_AUT0(u_char *aut0); | ||
65 | |||
60 | /* interface to libsectok */ | 66 | /* interface to libsectok */ |
61 | 67 | ||
62 | static int | 68 | static 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 | } | ||
272 | err: | 286 | err: |
273 | if (padded) | 287 | if (padded) |
274 | xfree(padded); | 288 | xfree(padded); |
@@ -340,7 +354,7 @@ sc_close(void) | |||
340 | } | 354 | } |
341 | 355 | ||
342 | Key * | 356 | Key * |
343 | sc_get_key(const char *id) | 357 | sc_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 | ||
379 | static int | 397 | static void |
380 | get_AUT0(char *aut0) | 398 | sc_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 | |||
408 | static int | ||
409 | get_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, |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: scard.h,v 1.8 2002/03/21 16:54:53 markus Exp $ */ | 1 | /* $OpenBSD: scard.h,v 1.9 2002/03/21 21:54:34 rees Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
@@ -35,7 +35,7 @@ | |||
35 | #define SCARD_ERROR_NOCARD -2 | 35 | #define SCARD_ERROR_NOCARD -2 |
36 | #define SCARD_ERROR_APPLET -3 | 36 | #define SCARD_ERROR_APPLET -3 |
37 | 37 | ||
38 | Key *sc_get_key(const char*); | 38 | Key *sc_get_key(const char*, const char*); |
39 | ENGINE *sc_get_engine(void); | 39 | ENGINE *sc_get_engine(void); |
40 | void sc_close(void); | 40 | void sc_close(void); |
41 | int sc_put_key(Key *, const char*); | 41 | int sc_put_key(Key *, const char*); |
diff --git a/ssh-keygen.c b/ssh-keygen.c index d14c99004..7d3629365 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c | |||
@@ -12,7 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "includes.h" | 14 | #include "includes.h" |
15 | RCSID("$OpenBSD: ssh-keygen.c,v 1.95 2002/03/21 16:54:53 markus Exp $"); | 15 | RCSID("$OpenBSD: ssh-keygen.c,v 1.96 2002/03/21 21:54:34 rees Exp $"); |
16 | 16 | ||
17 | #include <openssl/evp.h> | 17 | #include <openssl/evp.h> |
18 | #include <openssl/pem.h> | 18 | #include <openssl/pem.h> |
@@ -418,7 +418,7 @@ do_download(struct passwd *pw, const char *sc_reader_id) | |||
418 | { | 418 | { |
419 | Key *pub = NULL; | 419 | Key *pub = NULL; |
420 | 420 | ||
421 | pub = sc_get_key(sc_reader_id); | 421 | pub = sc_get_key(sc_reader_id, NULL); |
422 | if (pub == NULL) | 422 | if (pub == NULL) |
423 | fatal("cannot read public key from smartcard"); | 423 | fatal("cannot read public key from smartcard"); |
424 | key_write(pub, stdout); | 424 | key_write(pub, stdout); |