=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/ssh-keygen.c,v retrieving revision 1.370 retrieving revision 1.374 diff -u -r1.370 -r1.374 --- src/usr.bin/ssh/ssh-keygen.c 2019/11/25 00:51:37 1.370 +++ src/usr.bin/ssh/ssh-keygen.c 2019/12/10 22:37:20 1.374 @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.370 2019/11/25 00:51:37 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.374 2019/12/10 22:37:20 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -114,11 +114,12 @@ static u_int64_t cert_valid_to = ~0ULL; /* Certificate options */ -#define CERTOPT_X_FWD (1) -#define CERTOPT_AGENT_FWD (1<<1) -#define CERTOPT_PORT_FWD (1<<2) -#define CERTOPT_PTY (1<<3) -#define CERTOPT_USER_RC (1<<4) +#define CERTOPT_X_FWD (1) +#define CERTOPT_AGENT_FWD (1<<1) +#define CERTOPT_PORT_FWD (1<<2) +#define CERTOPT_PTY (1<<3) +#define CERTOPT_USER_RC (1<<4) +#define CERTOPT_NO_REQUIRE_USER_PRESENCE (1<<5) #define CERTOPT_DEFAULT (CERTOPT_X_FWD|CERTOPT_AGENT_FWD| \ CERTOPT_PORT_FWD|CERTOPT_PTY|CERTOPT_USER_RC) static u_int32_t certflags_flags = CERTOPT_DEFAULT; @@ -1646,6 +1647,9 @@ (certflags_flags & CERTOPT_USER_RC) != 0) add_flag_option(c, "permit-user-rc"); if ((which & OPTIONS_CRITICAL) != 0 && + (certflags_flags & CERTOPT_NO_REQUIRE_USER_PRESENCE) != 0) + add_flag_option(c, "no-touch-required"); + if ((which & OPTIONS_CRITICAL) != 0 && certflags_src_addr != NULL) add_string_option(c, "source-address", certflags_src_addr); for (i = 0; i < ncert_userext; i++) { @@ -1711,10 +1715,12 @@ int r, i, fd, found, agent_fd = -1; u_int n; struct sshkey *ca, *public; - char valid[64], *otmp, *tmp, *cp, *out, *comment, **plist = NULL; + char valid[64], *otmp, *tmp, *cp, *out, *comment; + char *ca_fp = NULL, **plist = NULL; FILE *f; struct ssh_identitylist *agent_ids; size_t j; + struct notifier_ctx *notifier = NULL; #ifdef ENABLE_PKCS11 pkcs11_init(1); @@ -1760,6 +1766,7 @@ fatal("CA key type %s doesn't match specified %s", sshkey_ssh_name(ca), key_type_name); } + ca_fp = sshkey_fingerprint(ca, fingerprint_hash, SSH_FP_DEFAULT); for (i = 0; i < argc; i++) { /* Split list of principals */ @@ -1810,8 +1817,16 @@ fatal("Couldn't certify key %s via agent: %s", tmp, ssh_err(r)); } else { - if ((r = sshkey_certify(public, ca, key_type_name, - sk_provider)) != 0) + if (sshkey_is_sk(ca) && + (ca->sk_flags & SSH_SK_USER_PRESENCE_REQD)) { + notifier = notify_start(0, + "Confirm user presence for key %s %s", + sshkey_type(ca), ca_fp); + } + r = sshkey_certify(public, ca, key_type_name, + sk_provider); + notify_complete(notifier); + if (r != 0) fatal("Couldn't certify key %s: %s", tmp, ssh_err(r)); } @@ -1849,6 +1864,7 @@ if (cert_serial_autoinc) cert_serial++; } + free(ca_fp); #ifdef ENABLE_PKCS11 pkcs11_terminate(); #endif @@ -1947,6 +1963,10 @@ certflags_flags &= ~CERTOPT_USER_RC; else if (strcasecmp(opt, "permit-user-rc") == 0) certflags_flags |= CERTOPT_USER_RC; + else if (strcasecmp(opt, "touch-required") == 0) + certflags_flags &= ~CERTOPT_NO_REQUIRE_USER_PRESENCE; + else if (strcasecmp(opt, "no-touch-required") == 0) + certflags_flags |= CERTOPT_NO_REQUIRE_USER_PRESENCE; else if (strncasecmp(opt, "force-command=", 14) == 0) { val = opt + 14; if (*val == '\0') @@ -2000,9 +2020,10 @@ strcmp(name, "permit-agent-forwarding") == 0 || strcmp(name, "permit-port-forwarding") == 0 || strcmp(name, "permit-pty") == 0 || - strcmp(name, "permit-user-rc") == 0)) + strcmp(name, "permit-user-rc") == 0 || + strcmp(name, "no-touch-required") == 0)) { printf("\n"); - else if (in_critical && + } else if (in_critical && (strcmp(name, "force-command") == 0 || strcmp(name, "source-address") == 0)) { if ((r = sshbuf_get_cstring(option, &arg, NULL)) != 0) @@ -2985,13 +3006,19 @@ case 'x': if (*optarg == '\0') fatal("Missing security key flags"); - ull = strtoull(optarg, &ep, 0); - if (*ep != '\0') - fatal("Security key flags \"%s\" is not a " - "number", optarg); - if (ull > 0xff) - fatal("Invalid security key flags 0x%llx", ull); - sk_flags = (uint8_t)ull; + if (strcasecmp(optarg, "no-touch-required") == 0) + sk_flags &= ~SSH_SK_USER_PRESENCE_REQD; + else { + ull = strtoull(optarg, &ep, 0); + if (*ep != '\0') + fatal("Security key flags \"%s\" is " + "not a number", optarg); + if (ull > 0xff) { + fatal("Invalid security key " + "flags 0x%llx", ull); + } + sk_flags = (uint8_t)ull; + } break; case 'z': errno = 0; @@ -3257,6 +3284,11 @@ switch (type) { case KEY_ECDSA_SK: case KEY_ED25519_SK: + if (!quiet) { + printf("You may need to touch your security key " + "to authorize key generation.\n"); + } + fflush(stdout); if (sshsk_enroll(type, sk_provider, cert_key_id == NULL ? "ssh:" : cert_key_id, sk_flags, NULL, &private, NULL) != 0)