-/* $OpenBSD: ssh-keygen.c,v 1.356 2019/10/16 06:03:30 djm Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.357 2019/10/31 21:17:09 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
#include "utf8.h"
#include "authfd.h"
#include "sshsig.h"
+#include "ssh-sk.h"
+#include "sk-api.h" /* XXX for SSH_SK_USER_PRESENCE_REQD; remove */
#ifdef WITH_OPENSSL
# define DEFAULT_KEY_TYPE_NAME "rsa"
/* Load key from this PKCS#11 provider */
static char *pkcs11provider = NULL;
+/* FIDO/U2F provider to use */
+static char *sk_provider = NULL;
+
/* Format for writing private keys */
static int private_key_format = SSHKEY_PRIVATE_OPENSSH;
case KEY_ECDSA:
name = _PATH_SSH_CLIENT_ID_ECDSA;
break;
+ case KEY_ECDSA_SK_CERT:
+ case KEY_ECDSA_SK:
+ name = _PATH_SSH_CLIENT_ID_ECDSA_SK;
+ break;
#endif
case KEY_RSA_CERT:
case KEY_RSA:
int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0;
int prefer_agent = 0, convert_to = 0, convert_from = 0;
int print_public = 0, print_generic = 0, cert_serial_autoinc = 0;
- unsigned long long cert_serial = 0;
+ unsigned long long ull, cert_serial = 0;
char *identity_comment = NULL, *ca_key_path = NULL;
u_int32_t bits = 0;
+ uint8_t sk_flags = SSH_SK_USER_PRESENCE_REQD;
FILE *f;
const char *errstr;
int log_level = SYSLOG_LEVEL_INFO;
if (gethostname(hostname, sizeof(hostname)) == -1)
fatal("gethostname: %s", strerror(errno));
- /* Remaining characters: dw */
+ sk_provider = getenv("SSH_SK_PROVIDER");
+
+ /* Remaining character: d */
while ((opt = getopt(argc, argv, "ABHLQUXceghiklopquvxy"
"C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Y:Z:"
- "a:b:f:g:j:m:n:r:s:t:z:")) != -1) {
+ "a:b:f:g:j:m:n:r:s:t:w:x:z:")) != -1) {
switch (opt) {
case 'A':
gen_all_hostkeys = 1;
quiet = 1;
break;
case 'e':
- case 'x':
/* export key */
convert_to = 1;
break;
break;
case 'Y':
sign_op = optarg;
+ case 'w':
+ sk_provider = optarg;
+ break;
+ 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;
break;
case 'z':
errno = 0;
if (!quiet)
printf("Generating public/private %s key pair.\n",
key_type_name);
- if ((r = sshkey_generate(type, bits, &private)) != 0)
+ if (type == KEY_ECDSA_SK) {
+ if (sshsk_enroll(sk_provider,
+ cert_key_id == NULL ? "ssh:" : cert_key_id,
+ sk_flags, NULL, &private, NULL) != 0)
+ exit(1); /* error message already printed */
+ } else if ((r = sshkey_generate(type, bits, &private)) != 0)
fatal("sshkey_generate failed");
if ((r = sshkey_from_private(private, &public)) != 0)
fatal("sshkey_from_private failed: %s\n", ssh_err(r));