diff options
author | djm@openbsd.org <djm@openbsd.org> | 2019-12-30 09:23:28 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2019-12-30 20:59:33 +1100 |
commit | c54cd1892c3e7f268b21e1f07ada9f0d9816ffc0 (patch) | |
tree | 71f801c4734b81311ec04f8bba13376c0d6591b0 /ssh-sk.c | |
parent | 79fe22d9bc2868c5118f032ec1200ac9c2e3aaef (diff) |
upstream: SK API and sk-helper error/PIN passing
Allow passing a PIN via the SK API (API major crank) and let the
ssh-sk-helper API follow.
Also enhance the ssh-sk-helper API to support passing back an error
code instead of a complete reply. Will be used to signal "wrong PIN",
etc.
feedback and ok markus@
OpenBSD-Commit-ID: a1bd6b0a2421646919a0c139b8183ad76d28fb71
Diffstat (limited to 'ssh-sk.c')
-rw-r--r-- | ssh-sk.c | 31 |
1 files changed, 17 insertions, 14 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-sk.c,v 1.20 2019/12/30 09:21:16 djm Exp $ */ | 1 | /* $OpenBSD: ssh-sk.c,v 1.21 2019/12/30 09:23:28 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2019 Google LLC | 3 | * Copyright (c) 2019 Google LLC |
4 | * | 4 | * |
@@ -53,13 +53,14 @@ struct sshsk_provider { | |||
53 | /* Enroll a U2F key (private key generation) */ | 53 | /* Enroll a U2F key (private key generation) */ |
54 | int (*sk_enroll)(int alg, const uint8_t *challenge, | 54 | int (*sk_enroll)(int alg, const uint8_t *challenge, |
55 | size_t challenge_len, const char *application, uint8_t flags, | 55 | size_t challenge_len, const char *application, uint8_t flags, |
56 | struct sk_enroll_response **enroll_response); | 56 | const char *pin, struct sk_enroll_response **enroll_response); |
57 | 57 | ||
58 | /* Sign a challenge */ | 58 | /* Sign a challenge */ |
59 | int (*sk_sign)(int alg, const uint8_t *message, size_t message_len, | 59 | int (*sk_sign)(int alg, const uint8_t *message, size_t message_len, |
60 | const char *application, | 60 | const char *application, |
61 | const uint8_t *key_handle, size_t key_handle_len, | 61 | const uint8_t *key_handle, size_t key_handle_len, |
62 | uint8_t flags, struct sk_sign_response **sign_response); | 62 | uint8_t flags, const char *pin, |
63 | struct sk_sign_response **sign_response); | ||
63 | 64 | ||
64 | /* Enumerate resident keys */ | 65 | /* Enumerate resident keys */ |
65 | int (*sk_load_resident_keys)(const char *pin, | 66 | int (*sk_load_resident_keys)(const char *pin, |
@@ -69,11 +70,11 @@ struct sshsk_provider { | |||
69 | /* Built-in version */ | 70 | /* Built-in version */ |
70 | int ssh_sk_enroll(int alg, const uint8_t *challenge, | 71 | int ssh_sk_enroll(int alg, const uint8_t *challenge, |
71 | size_t challenge_len, const char *application, uint8_t flags, | 72 | size_t challenge_len, const char *application, uint8_t flags, |
72 | struct sk_enroll_response **enroll_response); | 73 | const char *pin, struct sk_enroll_response **enroll_response); |
73 | int ssh_sk_sign(int alg, const uint8_t *message, size_t message_len, | 74 | int ssh_sk_sign(int alg, const uint8_t *message, size_t message_len, |
74 | const char *application, | 75 | const char *application, |
75 | const uint8_t *key_handle, size_t key_handle_len, | 76 | const uint8_t *key_handle, size_t key_handle_len, |
76 | uint8_t flags, struct sk_sign_response **sign_response); | 77 | uint8_t flags, const char *pin, struct sk_sign_response **sign_response); |
77 | int ssh_sk_load_resident_keys(const char *pin, | 78 | int ssh_sk_load_resident_keys(const char *pin, |
78 | struct sk_resident_key ***rks, size_t *nrks); | 79 | struct sk_resident_key ***rks, size_t *nrks); |
79 | 80 | ||
@@ -326,8 +327,8 @@ sshsk_key_from_response(int alg, const char *application, uint8_t flags, | |||
326 | 327 | ||
327 | int | 328 | int |
328 | sshsk_enroll(int type, const char *provider_path, const char *application, | 329 | sshsk_enroll(int type, const char *provider_path, const char *application, |
329 | uint8_t flags, struct sshbuf *challenge_buf, struct sshkey **keyp, | 330 | uint8_t flags, const char *pin, struct sshbuf *challenge_buf, |
330 | struct sshbuf *attest) | 331 | struct sshkey **keyp, struct sshbuf *attest) |
331 | { | 332 | { |
332 | struct sshsk_provider *skp = NULL; | 333 | struct sshsk_provider *skp = NULL; |
333 | struct sshkey *key = NULL; | 334 | struct sshkey *key = NULL; |
@@ -339,8 +340,9 @@ sshsk_enroll(int type, const char *provider_path, const char *application, | |||
339 | int alg; | 340 | int alg; |
340 | 341 | ||
341 | debug("%s: provider \"%s\", application \"%s\", flags 0x%02x, " | 342 | debug("%s: provider \"%s\", application \"%s\", flags 0x%02x, " |
342 | "challenge len %zu", __func__, provider_path, application, | 343 | "challenge len %zu%s", __func__, provider_path, application, |
343 | flags, challenge_buf == NULL ? 0 : sshbuf_len(challenge_buf)); | 344 | flags, challenge_buf == NULL ? 0 : sshbuf_len(challenge_buf), |
345 | (pin != NULL && *pin != '\0') ? " with-pin" : ""); | ||
344 | 346 | ||
345 | *keyp = NULL; | 347 | *keyp = NULL; |
346 | if (attest) | 348 | if (attest) |
@@ -391,7 +393,7 @@ sshsk_enroll(int type, const char *provider_path, const char *application, | |||
391 | /* XXX validate flags? */ | 393 | /* XXX validate flags? */ |
392 | /* enroll key */ | 394 | /* enroll key */ |
393 | if ((r = skp->sk_enroll(alg, challenge, challenge_len, application, | 395 | if ((r = skp->sk_enroll(alg, challenge, challenge_len, application, |
394 | flags, &resp)) != 0) { | 396 | flags, pin, &resp)) != 0) { |
395 | error("Security key provider %s returned failure %d", | 397 | error("Security key provider %s returned failure %d", |
396 | provider_path, r); | 398 | provider_path, r); |
397 | r = SSH_ERR_INVALID_FORMAT; /* XXX error codes in API? */ | 399 | r = SSH_ERR_INVALID_FORMAT; /* XXX error codes in API? */ |
@@ -504,7 +506,7 @@ sshsk_ed25519_sig(struct sk_sign_response *resp, struct sshbuf *sig) | |||
504 | int | 506 | int |
505 | sshsk_sign(const char *provider_path, struct sshkey *key, | 507 | sshsk_sign(const char *provider_path, struct sshkey *key, |
506 | u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, | 508 | u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, |
507 | u_int compat) | 509 | u_int compat, const char *pin) |
508 | { | 510 | { |
509 | struct sshsk_provider *skp = NULL; | 511 | struct sshsk_provider *skp = NULL; |
510 | int r = SSH_ERR_INTERNAL_ERROR; | 512 | int r = SSH_ERR_INTERNAL_ERROR; |
@@ -513,8 +515,9 @@ sshsk_sign(const char *provider_path, struct sshkey *key, | |||
513 | struct sshbuf *inner_sig = NULL, *sig = NULL; | 515 | struct sshbuf *inner_sig = NULL, *sig = NULL; |
514 | uint8_t message[32]; | 516 | uint8_t message[32]; |
515 | 517 | ||
516 | debug("%s: provider \"%s\", key %s, flags 0x%02x", __func__, | 518 | debug("%s: provider \"%s\", key %s, flags 0x%02x%s", __func__, |
517 | provider_path, sshkey_type(key), key->sk_flags); | 519 | provider_path, sshkey_type(key), key->sk_flags, |
520 | (pin != NULL && *pin != '\0') ? " with-pin" : ""); | ||
518 | 521 | ||
519 | if (sigp != NULL) | 522 | if (sigp != NULL) |
520 | *sigp = NULL; | 523 | *sigp = NULL; |
@@ -554,7 +557,7 @@ sshsk_sign(const char *provider_path, struct sshkey *key, | |||
554 | if ((r = skp->sk_sign(alg, message, sizeof(message), | 557 | if ((r = skp->sk_sign(alg, message, sizeof(message), |
555 | key->sk_application, | 558 | key->sk_application, |
556 | sshbuf_ptr(key->sk_key_handle), sshbuf_len(key->sk_key_handle), | 559 | sshbuf_ptr(key->sk_key_handle), sshbuf_len(key->sk_key_handle), |
557 | key->sk_flags, &resp)) != 0) { | 560 | key->sk_flags, pin, &resp)) != 0) { |
558 | debug("%s: sk_sign failed with code %d", __func__, r); | 561 | debug("%s: sk_sign failed with code %d", __func__, r); |
559 | goto out; | 562 | goto out; |
560 | } | 563 | } |