summaryrefslogtreecommitdiff
path: root/ssh-keygen.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2020-01-28 08:01:34 +0000
committerDamien Miller <djm@mindrot.org>2020-01-29 18:52:55 +1100
commit24c0f752adf9021277a7b0a84931bb5fe48ea379 (patch)
treecd1b9474e73ad7647b4ad88775365e7430d3fe64 /ssh-keygen.c
parent156bef36f93a48212383235bb8e3d71eaf2b2777 (diff)
upstream: changes to support FIDO attestation
Allow writing to disk the attestation certificate that is generated by the FIDO token at key enrollment time. These certificates may be used by an out-of-band workflow to prove that a particular key is held in trustworthy hardware. Allow passing in a challenge that will be sent to the card during key enrollment. These are needed to build an attestation workflow that resists replay attacks. ok markus@ OpenBSD-Commit-ID: 457dc3c3d689ba39eed328f0817ed9b91a5f78f6
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r--ssh-keygen.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 8df55f2c2..4ee43ab98 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.394 2020/01/25 23:13:09 djm Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.395 2020/01/28 08:01:34 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -3114,6 +3114,8 @@ main(int argc, char **argv)
3114 unsigned long long cert_serial = 0; 3114 unsigned long long cert_serial = 0;
3115 char *identity_comment = NULL, *ca_key_path = NULL, **opts = NULL; 3115 char *identity_comment = NULL, *ca_key_path = NULL, **opts = NULL;
3116 char *sk_application = NULL, *sk_device = NULL, *sk_user = NULL; 3116 char *sk_application = NULL, *sk_device = NULL, *sk_user = NULL;
3117 char *sk_attestaion_path = NULL;
3118 struct sshbuf *challenge = NULL, *attest = NULL;
3117 size_t i, nopts = 0; 3119 size_t i, nopts = 0;
3118 u_int32_t bits = 0; 3120 u_int32_t bits = 0;
3119 uint8_t sk_flags = SSH_SK_USER_PRESENCE_REQD; 3121 uint8_t sk_flags = SSH_SK_USER_PRESENCE_REQD;
@@ -3557,6 +3559,16 @@ main(int argc, char **argv)
3557 sk_device = xstrdup(opts[i] + 7); 3559 sk_device = xstrdup(opts[i] + 7);
3558 } else if (strncasecmp(opts[i], "user=", 5) == 0) { 3560 } else if (strncasecmp(opts[i], "user=", 5) == 0) {
3559 sk_user = xstrdup(opts[i] + 5); 3561 sk_user = xstrdup(opts[i] + 5);
3562 } else if (strncasecmp(opts[i], "challenge=", 10) == 0) {
3563 if ((r = sshbuf_load_file(opts[i] + 10,
3564 &challenge)) != 0) {
3565 fatal("Unable to load FIDO enrollment "
3566 "challenge \"%s\": %s",
3567 opts[i] + 10, ssh_err(r));
3568 }
3569 } else if (strncasecmp(opts[i],
3570 "write-attestation=", 18) == 0) {
3571 sk_attestaion_path = opts[i] + 18;
3560 } else if (strncasecmp(opts[i], 3572 } else if (strncasecmp(opts[i],
3561 "application=", 12) == 0) { 3573 "application=", 12) == 0) {
3562 sk_application = xstrdup(opts[i] + 12); 3574 sk_application = xstrdup(opts[i] + 12);
@@ -3570,12 +3582,14 @@ main(int argc, char **argv)
3570 "to authorize key generation.\n"); 3582 "to authorize key generation.\n");
3571 } 3583 }
3572 passphrase = NULL; 3584 passphrase = NULL;
3585 if ((attest = sshbuf_new()) == NULL)
3586 fatal("sshbuf_new failed");
3573 for (i = 0 ; i < 3; i++) { 3587 for (i = 0 ; i < 3; i++) {
3574 fflush(stdout); 3588 fflush(stdout);
3575 r = sshsk_enroll(type, sk_provider, sk_device, 3589 r = sshsk_enroll(type, sk_provider, sk_device,
3576 sk_application == NULL ? "ssh:" : sk_application, 3590 sk_application == NULL ? "ssh:" : sk_application,
3577 sk_user, sk_flags, passphrase, NULL, 3591 sk_user, sk_flags, passphrase, challenge,
3578 &private, NULL); 3592 &private, attest);
3579 if (r == 0) 3593 if (r == 0)
3580 break; 3594 break;
3581 if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) 3595 if (r != SSH_ERR_KEY_WRONG_PASSPHRASE)
@@ -3668,6 +3682,22 @@ main(int argc, char **argv)
3668 free(fp); 3682 free(fp);
3669 } 3683 }
3670 3684
3685 if (sk_attestaion_path != NULL) {
3686 if (attest == NULL || sshbuf_len(attest) == 0) {
3687 fatal("Enrollment did not return attestation "
3688 "certificate");
3689 }
3690 if ((r = sshbuf_write_file(sk_attestaion_path, attest)) != 0) {
3691 fatal("Unable to write attestation certificate "
3692 "\"%s\": %s", sk_attestaion_path, ssh_err(r));
3693 }
3694 if (!quiet) {
3695 printf("Your FIDO attestation certificate has been "
3696 "saved in %s\n", sk_attestaion_path);
3697 }
3698 }
3699 sshbuf_free(attest);
3671 sshkey_free(public); 3700 sshkey_free(public);
3701
3672 exit(0); 3702 exit(0);
3673} 3703}