summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--authfd.c4
-rw-r--r--myproposal.h4
-rw-r--r--pathnames.h3
-rw-r--r--readconf.c4
-rw-r--r--ssh-add.c5
-rw-r--r--ssh-agent.c4
-rw-r--r--ssh-keygen.c25
-rw-r--r--ssh-sk-helper.c4
-rw-r--r--sshconnect.c4
-rw-r--r--sshconnect2.c13
-rw-r--r--sshkey.c154
-rw-r--r--sshkey.h7
12 files changed, 200 insertions, 31 deletions
diff --git a/authfd.c b/authfd.c
index 1f0cd2ab3..e014f765c 100644
--- a/authfd.c
+++ b/authfd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfd.c,v 1.118 2019/10/31 21:19:14 djm Exp $ */ 1/* $OpenBSD: authfd.c,v 1.119 2019/11/12 19:33:08 markus Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -484,6 +484,8 @@ ssh_add_identity_constrained(int sock, struct sshkey *key,
484#endif 484#endif
485 case KEY_ED25519: 485 case KEY_ED25519:
486 case KEY_ED25519_CERT: 486 case KEY_ED25519_CERT:
487 case KEY_ED25519_SK:
488 case KEY_ED25519_SK_CERT:
487 case KEY_XMSS: 489 case KEY_XMSS:
488 case KEY_XMSS_CERT: 490 case KEY_XMSS_CERT:
489 type = constrained ? 491 type = constrained ?
diff --git a/myproposal.h b/myproposal.h
index a22649a2e..90bb67bb3 100644
--- a/myproposal.h
+++ b/myproposal.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: myproposal.h,v 1.60 2019/11/01 02:32:05 djm Exp $ */ 1/* $OpenBSD: myproposal.h,v 1.61 2019/11/12 19:33:08 markus Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -149,6 +149,7 @@
149 "ecdsa-sha2-nistp256-cert-v01@openssh.com," \ 149 "ecdsa-sha2-nistp256-cert-v01@openssh.com," \
150 "ecdsa-sha2-nistp384-cert-v01@openssh.com," \ 150 "ecdsa-sha2-nistp384-cert-v01@openssh.com," \
151 "ecdsa-sha2-nistp521-cert-v01@openssh.com," \ 151 "ecdsa-sha2-nistp521-cert-v01@openssh.com," \
152 "sk-ssh-ed25519-cert-v01@openssh.com," \
152 "ssh-ed25519-cert-v01@openssh.com," \ 153 "ssh-ed25519-cert-v01@openssh.com," \
153 "rsa-sha2-512-cert-v01@openssh.com," \ 154 "rsa-sha2-512-cert-v01@openssh.com," \
154 "rsa-sha2-256-cert-v01@openssh.com," \ 155 "rsa-sha2-256-cert-v01@openssh.com," \
@@ -157,6 +158,7 @@
157 "ecdsa-sha2-nistp256," \ 158 "ecdsa-sha2-nistp256," \
158 "ecdsa-sha2-nistp384," \ 159 "ecdsa-sha2-nistp384," \
159 "ecdsa-sha2-nistp521," \ 160 "ecdsa-sha2-nistp521," \
161 "sk-ssh-ed25519@openssh.com," \
160 "ssh-ed25519," \ 162 "ssh-ed25519," \
161 "rsa-sha2-512," \ 163 "rsa-sha2-512," \
162 "rsa-sha2-256," \ 164 "rsa-sha2-256," \
diff --git a/pathnames.h b/pathnames.h
index 3a1bd1977..f7ca5a75a 100644
--- a/pathnames.h
+++ b/pathnames.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: pathnames.h,v 1.30 2019/10/31 21:22:01 djm Exp $ */ 1/* $OpenBSD: pathnames.h,v 1.31 2019/11/12 19:33:08 markus Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -78,6 +78,7 @@
78#define _PATH_SSH_CLIENT_ID_ED25519 _PATH_SSH_USER_DIR "/id_ed25519" 78#define _PATH_SSH_CLIENT_ID_ED25519 _PATH_SSH_USER_DIR "/id_ed25519"
79#define _PATH_SSH_CLIENT_ID_XMSS _PATH_SSH_USER_DIR "/id_xmss" 79#define _PATH_SSH_CLIENT_ID_XMSS _PATH_SSH_USER_DIR "/id_xmss"
80#define _PATH_SSH_CLIENT_ID_ECDSA_SK _PATH_SSH_USER_DIR "/id_ecdsa_sk" 80#define _PATH_SSH_CLIENT_ID_ECDSA_SK _PATH_SSH_USER_DIR "/id_ecdsa_sk"
81#define _PATH_SSH_CLIENT_ID_ED25519_SK _PATH_SSH_USER_DIR "/id_ed25519_sk"
81 82
82/* 83/*
83 * Configuration file in user's home directory. This file need not be 84 * Configuration file in user's home directory. This file need not be
diff --git a/readconf.c b/readconf.c
index f18194580..3d99367c3 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.c,v 1.310 2019/10/31 21:18:28 djm Exp $ */ 1/* $OpenBSD: readconf.c,v 1.311 2019/11/12 19:33:08 markus Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -2055,6 +2055,8 @@ fill_default_options(Options * options)
2055#endif 2055#endif
2056 add_identity_file(options, "~/", 2056 add_identity_file(options, "~/",
2057 _PATH_SSH_CLIENT_ID_ED25519, 0); 2057 _PATH_SSH_CLIENT_ID_ED25519, 0);
2058 add_identity_file(options, "~/",
2059 _PATH_SSH_CLIENT_ID_ED25519_SK, 0);
2058 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_XMSS, 0); 2060 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_XMSS, 0);
2059 } 2061 }
2060 if (options->escape_char == -1) 2062 if (options->escape_char == -1)
diff --git a/ssh-add.c b/ssh-add.c
index 3c8849ac4..696b156d5 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-add.c,v 1.143 2019/10/31 21:19:56 djm Exp $ */ 1/* $OpenBSD: ssh-add.c,v 1.144 2019/11/12 19:33:08 markus Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -81,6 +81,7 @@ static char *default_files[] = {
81#endif 81#endif
82#endif /* WITH_OPENSSL */ 82#endif /* WITH_OPENSSL */
83 _PATH_SSH_CLIENT_ID_ED25519, 83 _PATH_SSH_CLIENT_ID_ED25519,
84 _PATH_SSH_CLIENT_ID_ED25519_SK,
84 _PATH_SSH_CLIENT_ID_XMSS, 85 _PATH_SSH_CLIENT_ID_XMSS,
85 NULL 86 NULL
86}; 87};
@@ -312,7 +313,7 @@ add_file(int agent_fd, const char *filename, int key_only, int qflag,
312 ssh_free_identitylist(idlist); 313 ssh_free_identitylist(idlist);
313 } 314 }
314 315
315 if (sshkey_type_plain(private->type) != KEY_ECDSA_SK) 316 if (!sshkey_is_sk(private))
316 skprovider = NULL; /* Don't send constraint for other keys */ 317 skprovider = NULL; /* Don't send constraint for other keys */
317 else if (skprovider == NULL) { 318 else if (skprovider == NULL) {
318 fprintf(stderr, "Cannot load security key %s without " 319 fprintf(stderr, "Cannot load security key %s without "
diff --git a/ssh-agent.c b/ssh-agent.c
index 07f19c53a..dd9f85ae7 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.239 2019/10/31 21:23:19 djm Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.240 2019/11/12 19:33:08 markus Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -622,7 +622,7 @@ process_add_identity(SocketEntry *e)
622 } 622 }
623 } 623 }
624 if (sk_provider != NULL) { 624 if (sk_provider != NULL) {
625 if (sshkey_type_plain(k->type) != KEY_ECDSA_SK) { 625 if (!sshkey_is_sk(k)) {
626 error("Cannot add provider: %s is not a security key", 626 error("Cannot add provider: %s is not a security key",
627 sshkey_type(k)); 627 sshkey_type(k));
628 free(sk_provider); 628 free(sk_provider);
diff --git a/ssh-keygen.c b/ssh-keygen.c
index ac34f314b..030b3684e 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.361 2019/11/08 03:54:02 djm Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.362 2019/11/12 19:33:08 markus 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
@@ -287,6 +287,10 @@ ask_filename(struct passwd *pw, const char *prompt)
287 case KEY_ED25519_CERT: 287 case KEY_ED25519_CERT:
288 name = _PATH_SSH_CLIENT_ID_ED25519; 288 name = _PATH_SSH_CLIENT_ID_ED25519;
289 break; 289 break;
290 case KEY_ED25519_SK:
291 case KEY_ED25519_SK_CERT:
292 name = _PATH_SSH_CLIENT_ID_ED25519_SK;
293 break;
290 case KEY_XMSS: 294 case KEY_XMSS:
291 case KEY_XMSS_CERT: 295 case KEY_XMSS_CERT:
292 name = _PATH_SSH_CLIENT_ID_XMSS; 296 name = _PATH_SSH_CLIENT_ID_XMSS;
@@ -3255,16 +3259,23 @@ main(int argc, char **argv)
3255 printf("Generating public/private %s key pair.\n", 3259 printf("Generating public/private %s key pair.\n",
3256 key_type_name); 3260 key_type_name);
3257 if (type == KEY_ECDSA_SK) { 3261 if (type == KEY_ECDSA_SK) {
3262 switch (type) {
3263 case KEY_ECDSA_SK:
3264 case KEY_ED25519_SK:
3258#ifndef ENABLE_SK 3265#ifndef ENABLE_SK
3259 fatal("Security key support was disabled at compile time"); 3266 fatal("Security key support was disabled at compile time");
3260#else /* ENABLE_SK */ 3267#else /* ENABLE_SK */
3261 if (sshsk_enroll(sk_provider, 3268 if (sshsk_enroll(type, sk_provider,
3262 cert_key_id == NULL ? "ssh:" : cert_key_id, 3269 cert_key_id == NULL ? "ssh:" : cert_key_id,
3263 sk_flags, NULL, &private, NULL) != 0) 3270 sk_flags, NULL, &private, NULL) != 0)
3264 exit(1); /* error message already printed */ 3271 exit(1); /* error message already printed */
3272 break;
3265#endif /* ENABLE_SK */ 3273#endif /* ENABLE_SK */
3266 } else if ((r = sshkey_generate(type, bits, &private)) != 0) 3274 default:
3267 fatal("sshkey_generate failed"); 3275 if ((r = sshkey_generate(type, bits, &private)) != 0)
3276 fatal("sshkey_generate failed");
3277 break;
3278 }
3268 if ((r = sshkey_from_private(private, &public)) != 0) 3279 if ((r = sshkey_from_private(private, &public)) != 0)
3269 fatal("sshkey_from_private failed: %s\n", ssh_err(r)); 3280 fatal("sshkey_from_private failed: %s\n", ssh_err(r));
3270 3281
diff --git a/ssh-sk-helper.c b/ssh-sk-helper.c
index a996f5898..0acb8d172 100644
--- a/ssh-sk-helper.c
+++ b/ssh-sk-helper.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-sk-helper.c,v 1.2 2019/11/12 19:30:50 markus Exp $ */ 1/* $OpenBSD: ssh-sk-helper.c,v 1.3 2019/11/12 19:33:08 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2019 Google LLC 3 * Copyright (c) 2019 Google LLC
4 * 4 *
@@ -114,7 +114,7 @@ main(int argc, char **argv)
114 if ((r = sshbuf_froms(req, &kbuf)) != 0 || 114 if ((r = sshbuf_froms(req, &kbuf)) != 0 ||
115 (r = sshkey_private_deserialize(kbuf, &key)) != 0) 115 (r = sshkey_private_deserialize(kbuf, &key)) != 0)
116 fatal("Unable to parse key: %s", ssh_err(r)); 116 fatal("Unable to parse key: %s", ssh_err(r));
117 if (sshkey_type_plain(key->type) != KEY_ECDSA_SK) 117 if (!sshkey_is_sk(key))
118 fatal("Unsupported key type %s", sshkey_ssh_name(key)); 118 fatal("Unsupported key type %s", sshkey_ssh_name(key));
119 119
120 if ((r = sshbuf_get_cstring(req, &provider, NULL)) != 0 || 120 if ((r = sshbuf_get_cstring(req, &provider, NULL)) != 0 ||
diff --git a/sshconnect.c b/sshconnect.c
index 177775f6e..7e9369ee3 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.c,v 1.321 2019/10/31 21:20:38 djm Exp $ */ 1/* $OpenBSD: sshconnect.c,v 1.322 2019/11/12 19:33:08 markus Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1425,7 +1425,7 @@ maybe_add_key_to_agent(char *authfile, struct sshkey *private,
1425 close(auth_sock); 1425 close(auth_sock);
1426 return; 1426 return;
1427 } 1427 }
1428 if (sshkey_type_plain(private->type) == KEY_ECDSA_SK) 1428 if (sshkey_is_sk(private))
1429 skprovider = options.sk_provider; 1429 skprovider = options.sk_provider;
1430 if ((r = ssh_add_identity_constrained(auth_sock, private, comment, 0, 1430 if ((r = ssh_add_identity_constrained(auth_sock, private, comment, 0,
1431 (options.add_keys_to_agent == 3), 0, skprovider)) == 0) 1431 (options.add_keys_to_agent == 3), 0, skprovider)) == 0)
diff --git a/sshconnect2.c b/sshconnect2.c
index 867d463d6..4e5cddf14 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect2.c,v 1.310 2019/10/31 21:23:19 djm Exp $ */ 1/* $OpenBSD: sshconnect2.c,v 1.311 2019/11/12 19:33:08 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Damien Miller. All rights reserved. 4 * Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -611,7 +611,7 @@ format_identity(Identity *id)
611 if (id->key) { 611 if (id->key) {
612 if ((id->key->flags & SSHKEY_FLAG_EXT) != 0) 612 if ((id->key->flags & SSHKEY_FLAG_EXT) != 0)
613 note = " token"; 613 note = " token";
614 else if (sshkey_type_plain(id->key->type) == KEY_ECDSA_SK) 614 else if (sshkey_is_sk(id->key))
615 note = " security-key"; 615 note = " security-key";
616 } 616 }
617 xasprintf(&ret, "%s %s%s%s%s%s%s", 617 xasprintf(&ret, "%s %s%s%s%s%s%s",
@@ -1468,8 +1468,7 @@ load_identity_file(Identity *id)
1468 quit = 1; 1468 quit = 1;
1469 break; 1469 break;
1470 } 1470 }
1471 if (private != NULL && 1471 if (private != NULL && sshkey_is_sk(private) &&
1472 sshkey_type_plain(private->type) == KEY_ECDSA_SK &&
1473 options.sk_provider == NULL) { 1472 options.sk_provider == NULL) {
1474 debug("key \"%s\" is a security key, but no " 1473 debug("key \"%s\" is a security key, but no "
1475 "provider specified", id->filename); 1474 "provider specified", id->filename);
@@ -1554,8 +1553,7 @@ pubkey_prepare(Authctxt *authctxt)
1554 options.identity_files[i]); 1553 options.identity_files[i]);
1555 continue; 1554 continue;
1556 } 1555 }
1557 if (key && sshkey_type_plain(key->type) == KEY_ECDSA_SK && 1556 if (key && sshkey_is_sk(key) && options.sk_provider == NULL) {
1558 options.sk_provider == NULL) {
1559 debug("%s: ignoring security key %s as no " 1557 debug("%s: ignoring security key %s as no "
1560 "SecurityKeyProvider has been specified", 1558 "SecurityKeyProvider has been specified",
1561 __func__, options.identity_files[i]); 1559 __func__, options.identity_files[i]);
@@ -1579,8 +1577,7 @@ pubkey_prepare(Authctxt *authctxt)
1579 options.identity_files[i]); 1577 options.identity_files[i]);
1580 continue; 1578 continue;
1581 } 1579 }
1582 if (key && sshkey_type_plain(key->type) == KEY_ECDSA_SK && 1580 if (key && sshkey_is_sk(key) && options.sk_provider == NULL) {
1583 options.sk_provider == NULL) {
1584 debug("%s: ignoring security key certificate %s as no " 1581 debug("%s: ignoring security key certificate %s as no "
1585 "SecurityKeyProvider has been specified", 1582 "SecurityKeyProvider has been specified",
1586 __func__, options.identity_files[i]); 1583 __func__, options.identity_files[i]);
diff --git a/sshkey.c b/sshkey.c
index 269f37b39..1b66d4ec7 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshkey.c,v 1.89 2019/11/12 19:31:18 markus Exp $ */ 1/* $OpenBSD: sshkey.c,v 1.90 2019/11/12 19:33:08 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved. 4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved.
@@ -107,6 +107,10 @@ static const struct keytype keytypes[] = {
107 { "ssh-ed25519", "ED25519", NULL, KEY_ED25519, 0, 0, 0 }, 107 { "ssh-ed25519", "ED25519", NULL, KEY_ED25519, 0, 0, 0 },
108 { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", NULL, 108 { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", NULL,
109 KEY_ED25519_CERT, 0, 1, 0 }, 109 KEY_ED25519_CERT, 0, 1, 0 },
110 { "sk-ssh-ed25519@openssh.com", "ED25519-SK", NULL,
111 KEY_ED25519_SK, 0, 0, 0 },
112 { "sk-ssh-ed25519-cert-v01@openssh.com", "ED25519-SK-CERT", NULL,
113 KEY_ED25519_SK_CERT, 0, 1, 0 },
110#ifdef WITH_XMSS 114#ifdef WITH_XMSS
111 { "ssh-xmss@openssh.com", "XMSS", NULL, KEY_XMSS, 0, 0, 0 }, 115 { "ssh-xmss@openssh.com", "XMSS", NULL, KEY_XMSS, 0, 0, 0 },
112 { "ssh-xmss-cert-v01@openssh.com", "XMSS-CERT", NULL, 116 { "ssh-xmss-cert-v01@openssh.com", "XMSS-CERT", NULL,
@@ -337,6 +341,8 @@ sshkey_size(const struct sshkey *k)
337#endif /* WITH_OPENSSL */ 341#endif /* WITH_OPENSSL */
338 case KEY_ED25519: 342 case KEY_ED25519:
339 case KEY_ED25519_CERT: 343 case KEY_ED25519_CERT:
344 case KEY_ED25519_SK:
345 case KEY_ED25519_SK_CERT:
340 case KEY_XMSS: 346 case KEY_XMSS:
341 case KEY_XMSS_CERT: 347 case KEY_XMSS_CERT:
342 return 256; /* XXX */ 348 return 256; /* XXX */
@@ -353,6 +359,7 @@ sshkey_type_is_valid_ca(int type)
353 case KEY_ECDSA: 359 case KEY_ECDSA:
354 case KEY_ECDSA_SK: 360 case KEY_ECDSA_SK:
355 case KEY_ED25519: 361 case KEY_ED25519:
362 case KEY_ED25519_SK:
356 case KEY_XMSS: 363 case KEY_XMSS:
357 return 1; 364 return 1;
358 default: 365 default:
@@ -368,6 +375,20 @@ sshkey_is_cert(const struct sshkey *k)
368 return sshkey_type_is_cert(k->type); 375 return sshkey_type_is_cert(k->type);
369} 376}
370 377
378int
379sshkey_is_sk(const struct sshkey *k)
380{
381 if (k == NULL)
382 return 0;
383 switch (sshkey_type_plain(k->type)) {
384 case KEY_ECDSA_SK:
385 case KEY_ED25519_SK:
386 return 1;
387 default:
388 return 0;
389 }
390}
391
371/* Return the cert-less equivalent to a certified key type */ 392/* Return the cert-less equivalent to a certified key type */
372int 393int
373sshkey_type_plain(int type) 394sshkey_type_plain(int type)
@@ -383,6 +404,8 @@ sshkey_type_plain(int type)
383 return KEY_ECDSA_SK; 404 return KEY_ECDSA_SK;
384 case KEY_ED25519_CERT: 405 case KEY_ED25519_CERT:
385 return KEY_ED25519; 406 return KEY_ED25519;
407 case KEY_ED25519_SK_CERT:
408 return KEY_ED25519_SK;
386 case KEY_XMSS_CERT: 409 case KEY_XMSS_CERT:
387 return KEY_XMSS; 410 return KEY_XMSS;
388 default: 411 default:
@@ -563,6 +586,8 @@ sshkey_new(int type)
563#endif /* WITH_OPENSSL */ 586#endif /* WITH_OPENSSL */
564 case KEY_ED25519: 587 case KEY_ED25519:
565 case KEY_ED25519_CERT: 588 case KEY_ED25519_CERT:
589 case KEY_ED25519_SK:
590 case KEY_ED25519_SK_CERT:
566 case KEY_XMSS: 591 case KEY_XMSS:
567 case KEY_XMSS_CERT: 592 case KEY_XMSS_CERT:
568 /* no need to prealloc */ 593 /* no need to prealloc */
@@ -615,6 +640,12 @@ sshkey_free(struct sshkey *k)
615 break; 640 break;
616# endif /* OPENSSL_HAS_ECC */ 641# endif /* OPENSSL_HAS_ECC */
617#endif /* WITH_OPENSSL */ 642#endif /* WITH_OPENSSL */
643 case KEY_ED25519_SK:
644 case KEY_ED25519_SK_CERT:
645 free(k->sk_application);
646 sshbuf_free(k->sk_key_handle);
647 sshbuf_free(k->sk_reserved);
648 /* FALLTHROUGH */
618 case KEY_ED25519: 649 case KEY_ED25519:
619 case KEY_ED25519_CERT: 650 case KEY_ED25519_CERT:
620 freezero(k->ed25519_pk, ED25519_PK_SZ); 651 freezero(k->ed25519_pk, ED25519_PK_SZ);
@@ -734,6 +765,13 @@ sshkey_equal_public(const struct sshkey *a, const struct sshkey *b)
734 return 1; 765 return 1;
735# endif /* OPENSSL_HAS_ECC */ 766# endif /* OPENSSL_HAS_ECC */
736#endif /* WITH_OPENSSL */ 767#endif /* WITH_OPENSSL */
768 case KEY_ED25519_SK:
769 case KEY_ED25519_SK_CERT:
770 if (a->sk_application == NULL || b->sk_application == NULL)
771 return 0;
772 if (strcmp(a->sk_application, b->sk_application) != 0)
773 return 0;
774 /* FALLTHROUGH */
737 case KEY_ED25519: 775 case KEY_ED25519:
738 case KEY_ED25519_CERT: 776 case KEY_ED25519_CERT:
739 return a->ed25519_pk != NULL && b->ed25519_pk != NULL && 777 return a->ed25519_pk != NULL && b->ed25519_pk != NULL &&
@@ -842,12 +880,18 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain,
842 break; 880 break;
843#endif /* WITH_OPENSSL */ 881#endif /* WITH_OPENSSL */
844 case KEY_ED25519: 882 case KEY_ED25519:
883 case KEY_ED25519_SK:
845 if (key->ed25519_pk == NULL) 884 if (key->ed25519_pk == NULL)
846 return SSH_ERR_INVALID_ARGUMENT; 885 return SSH_ERR_INVALID_ARGUMENT;
847 if ((ret = sshbuf_put_cstring(b, typename)) != 0 || 886 if ((ret = sshbuf_put_cstring(b, typename)) != 0 ||
848 (ret = sshbuf_put_string(b, 887 (ret = sshbuf_put_string(b,
849 key->ed25519_pk, ED25519_PK_SZ)) != 0) 888 key->ed25519_pk, ED25519_PK_SZ)) != 0)
850 return ret; 889 return ret;
890 if (type == KEY_ED25519_SK) {
891 if ((ret = sshbuf_put_cstring(b,
892 key->sk_application)) != 0)
893 return ret;
894 }
851 break; 895 break;
852#ifdef WITH_XMSS 896#ifdef WITH_XMSS
853 case KEY_XMSS: 897 case KEY_XMSS:
@@ -1290,11 +1334,13 @@ sshkey_read(struct sshkey *ret, char **cpp)
1290 case KEY_ECDSA: 1334 case KEY_ECDSA:
1291 case KEY_ECDSA_SK: 1335 case KEY_ECDSA_SK:
1292 case KEY_ED25519: 1336 case KEY_ED25519:
1337 case KEY_ED25519_SK:
1293 case KEY_DSA_CERT: 1338 case KEY_DSA_CERT:
1294 case KEY_ECDSA_CERT: 1339 case KEY_ECDSA_CERT:
1295 case KEY_ECDSA_SK_CERT: 1340 case KEY_ECDSA_SK_CERT:
1296 case KEY_RSA_CERT: 1341 case KEY_RSA_CERT:
1297 case KEY_ED25519_CERT: 1342 case KEY_ED25519_CERT:
1343 case KEY_ED25519_SK_CERT:
1298#ifdef WITH_XMSS 1344#ifdef WITH_XMSS
1299 case KEY_XMSS: 1345 case KEY_XMSS:
1300 case KEY_XMSS_CERT: 1346 case KEY_XMSS_CERT:
@@ -1418,6 +1464,13 @@ sshkey_read(struct sshkey *ret, char **cpp)
1418 /* XXX */ 1464 /* XXX */
1419#endif 1465#endif
1420 break; 1466 break;
1467 case KEY_ED25519_SK:
1468 freezero(ret->ed25519_pk, ED25519_PK_SZ);
1469 ret->ed25519_pk = k->ed25519_pk;
1470 ret->sk_application = k->sk_application;
1471 k->ed25519_pk = NULL;
1472 k->sk_application = NULL;
1473 break;
1421#ifdef WITH_XMSS 1474#ifdef WITH_XMSS
1422 case KEY_XMSS: 1475 case KEY_XMSS:
1423 free(ret->xmss_pk); 1476 free(ret->xmss_pk);
@@ -1876,6 +1929,8 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
1876#endif /* WITH_OPENSSL */ 1929#endif /* WITH_OPENSSL */
1877 case KEY_ED25519: 1930 case KEY_ED25519:
1878 case KEY_ED25519_CERT: 1931 case KEY_ED25519_CERT:
1932 case KEY_ED25519_SK:
1933 case KEY_ED25519_SK_CERT:
1879 if (k->ed25519_pk != NULL) { 1934 if (k->ed25519_pk != NULL) {
1880 if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) { 1935 if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) {
1881 r = SSH_ERR_ALLOC_FAIL; 1936 r = SSH_ERR_ALLOC_FAIL;
@@ -1883,6 +1938,12 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
1883 } 1938 }
1884 memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); 1939 memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ);
1885 } 1940 }
1941 if (k->type != KEY_ED25519_SK &&
1942 k->type != KEY_ED25519_SK_CERT)
1943 break;
1944 /* Append security-key application string */
1945 if ((n->sk_application = strdup(k->sk_application)) == NULL)
1946 goto out;
1886 break; 1947 break;
1887#ifdef WITH_XMSS 1948#ifdef WITH_XMSS
1888 case KEY_XMSS: 1949 case KEY_XMSS:
@@ -2444,6 +2505,7 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
2444# endif /* OPENSSL_HAS_ECC */ 2505# endif /* OPENSSL_HAS_ECC */
2445#endif /* WITH_OPENSSL */ 2506#endif /* WITH_OPENSSL */
2446 case KEY_ED25519_CERT: 2507 case KEY_ED25519_CERT:
2508 case KEY_ED25519_SK_CERT:
2447 /* Skip nonce */ 2509 /* Skip nonce */
2448 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { 2510 if (sshbuf_get_string_direct(b, NULL, NULL) != 0) {
2449 ret = SSH_ERR_INVALID_FORMAT; 2511 ret = SSH_ERR_INVALID_FORMAT;
@@ -2451,6 +2513,7 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
2451 } 2513 }
2452 /* FALLTHROUGH */ 2514 /* FALLTHROUGH */
2453 case KEY_ED25519: 2515 case KEY_ED25519:
2516 case KEY_ED25519_SK:
2454 if ((ret = sshbuf_get_string(b, &pk, &len)) != 0) 2517 if ((ret = sshbuf_get_string(b, &pk, &len)) != 0)
2455 goto out; 2518 goto out;
2456 if (len != ED25519_PK_SZ) { 2519 if (len != ED25519_PK_SZ) {
@@ -2461,6 +2524,17 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
2461 ret = SSH_ERR_ALLOC_FAIL; 2524 ret = SSH_ERR_ALLOC_FAIL;
2462 goto out; 2525 goto out;
2463 } 2526 }
2527 if (type == KEY_ED25519_SK || type == KEY_ED25519_SK_CERT) {
2528 /* Parse additional security-key application string */
2529 if (sshbuf_get_cstring(b, &key->sk_application,
2530 NULL) != 0) {
2531 ret = SSH_ERR_INVALID_FORMAT;
2532 goto out;
2533 }
2534#ifdef DEBUG_PK
2535 fprintf(stderr, "App: %s\n", key->sk_application);
2536#endif
2537 }
2464 key->ed25519_pk = pk; 2538 key->ed25519_pk = pk;
2465 pk = NULL; 2539 pk = NULL;
2466 break; 2540 break;
@@ -2790,6 +2864,9 @@ sshkey_to_certified(struct sshkey *k)
2790 newtype = KEY_ECDSA_SK_CERT; 2864 newtype = KEY_ECDSA_SK_CERT;
2791 break; 2865 break;
2792#endif /* WITH_OPENSSL */ 2866#endif /* WITH_OPENSSL */
2867 case KEY_ED25519_SK:
2868 newtype = KEY_ED25519_SK_CERT;
2869 break;
2793 case KEY_ED25519: 2870 case KEY_ED25519:
2794 newtype = KEY_ED25519_CERT; 2871 newtype = KEY_ED25519_CERT;
2795 break; 2872 break;
@@ -3223,6 +3300,29 @@ sshkey_private_serialize_opt(struct sshkey *key, struct sshbuf *buf,
3223 ED25519_SK_SZ)) != 0) 3300 ED25519_SK_SZ)) != 0)
3224 goto out; 3301 goto out;
3225 break; 3302 break;
3303 case KEY_ED25519_SK:
3304 if ((r = sshbuf_put_string(b, key->ed25519_pk,
3305 ED25519_PK_SZ)) != 0 ||
3306 (r = sshbuf_put_cstring(b, key->sk_application)) != 0 ||
3307 (r = sshbuf_put_u8(b, key->sk_flags)) != 0 ||
3308 (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 ||
3309 (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0)
3310 goto out;
3311 break;
3312 case KEY_ED25519_SK_CERT:
3313 if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) {
3314 r = SSH_ERR_INVALID_ARGUMENT;
3315 goto out;
3316 }
3317 if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 ||
3318 (r = sshbuf_put_string(b, key->ed25519_pk,
3319 ED25519_PK_SZ)) != 0 ||
3320 (r = sshbuf_put_cstring(b, key->sk_application)) != 0 ||
3321 (r = sshbuf_put_u8(b, key->sk_flags)) != 0 ||
3322 (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 ||
3323 (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0)
3324 goto out;
3325 break;
3226#ifdef WITH_XMSS 3326#ifdef WITH_XMSS
3227 case KEY_XMSS: 3327 case KEY_XMSS:
3228 if (key->xmss_name == NULL) { 3328 if (key->xmss_name == NULL) {
@@ -3532,6 +3632,57 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
3532 k->ed25519_sk = ed25519_sk; 3632 k->ed25519_sk = ed25519_sk;
3533 ed25519_pk = ed25519_sk = NULL; /* transferred */ 3633 ed25519_pk = ed25519_sk = NULL; /* transferred */
3534 break; 3634 break;
3635 case KEY_ED25519_SK:
3636 if ((k = sshkey_new(type)) == NULL) {
3637 r = SSH_ERR_ALLOC_FAIL;
3638 goto out;
3639 }
3640 if ((r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0)
3641 goto out;
3642 if (pklen != ED25519_PK_SZ) {
3643 r = SSH_ERR_INVALID_FORMAT;
3644 goto out;
3645 }
3646 if ((k->sk_key_handle = sshbuf_new()) == NULL ||
3647 (k->sk_reserved = sshbuf_new()) == NULL) {
3648 r = SSH_ERR_ALLOC_FAIL;
3649 goto out;
3650 }
3651 if ((r = sshbuf_get_cstring(buf, &k->sk_application,
3652 NULL)) != 0 ||
3653 (r = sshbuf_get_u8(buf, &k->sk_flags)) != 0 ||
3654 (r = sshbuf_get_stringb(buf, k->sk_key_handle)) != 0 ||
3655 (r = sshbuf_get_stringb(buf, k->sk_reserved)) != 0)
3656 goto out;
3657 k->ed25519_pk = ed25519_pk;
3658 ed25519_pk = NULL;
3659 break;
3660 case KEY_ED25519_SK_CERT:
3661 if ((r = sshkey_froms(buf, &k)) != 0 ||
3662 (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0)
3663 goto out;
3664 if (k->type != type) {
3665 r = SSH_ERR_INVALID_FORMAT;
3666 goto out;
3667 }
3668 if (pklen != ED25519_PK_SZ) {
3669 r = SSH_ERR_INVALID_FORMAT;
3670 goto out;
3671 }
3672 if ((k->sk_key_handle = sshbuf_new()) == NULL ||
3673 (k->sk_reserved = sshbuf_new()) == NULL) {
3674 r = SSH_ERR_ALLOC_FAIL;
3675 goto out;
3676 }
3677 if ((r = sshbuf_get_cstring(buf, &k->sk_application,
3678 NULL)) != 0 ||
3679 (r = sshbuf_get_u8(buf, &k->sk_flags)) != 0 ||
3680 (r = sshbuf_get_stringb(buf, k->sk_key_handle)) != 0 ||
3681 (r = sshbuf_get_stringb(buf, k->sk_reserved)) != 0)
3682 goto out;
3683 k->ed25519_pk = ed25519_pk;
3684 ed25519_pk = NULL; /* transferred */
3685 break;
3535#ifdef WITH_XMSS 3686#ifdef WITH_XMSS
3536 case KEY_XMSS: 3687 case KEY_XMSS:
3537 if ((k = sshkey_new(type)) == NULL) { 3688 if ((k = sshkey_new(type)) == NULL) {
@@ -4261,6 +4412,7 @@ sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
4261 break; /* see below */ 4412 break; /* see below */
4262#endif /* WITH_OPENSSL */ 4413#endif /* WITH_OPENSSL */
4263 case KEY_ED25519: 4414 case KEY_ED25519:
4415 case KEY_ED25519_SK:
4264#ifdef WITH_XMSS 4416#ifdef WITH_XMSS
4265 case KEY_XMSS: 4417 case KEY_XMSS:
4266#endif /* WITH_XMSS */ 4418#endif /* WITH_XMSS */
diff --git a/sshkey.h b/sshkey.h
index 8cd12bd95..1fb8369f0 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshkey.h,v 1.37 2019/11/12 19:29:25 markus Exp $ */ 1/* $OpenBSD: sshkey.h,v 1.38 2019/11/12 19:33:08 markus Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -129,7 +129,7 @@ struct sshkey {
129 /* KEY_ECDSA and KEY_ECDSA_SK */ 129 /* KEY_ECDSA and KEY_ECDSA_SK */
130 int ecdsa_nid; /* NID of curve */ 130 int ecdsa_nid; /* NID of curve */
131 EC_KEY *ecdsa; 131 EC_KEY *ecdsa;
132 /* KEY_ED25519 */ 132 /* KEY_ED25519 and KEY_ED25519_SK */
133 u_char *ed25519_sk; 133 u_char *ed25519_sk;
134 u_char *ed25519_pk; 134 u_char *ed25519_pk;
135 /* KEY_XMSS */ 135 /* KEY_XMSS */
@@ -138,7 +138,7 @@ struct sshkey {
138 void *xmss_state; /* depends on xmss_name, opaque */ 138 void *xmss_state; /* depends on xmss_name, opaque */
139 u_char *xmss_sk; 139 u_char *xmss_sk;
140 u_char *xmss_pk; 140 u_char *xmss_pk;
141 /* KEY_ECDSA_SK */ 141 /* KEY_ECDSA_SK and KEY_ED25519_SK */
142 char *sk_application; 142 char *sk_application;
143 uint8_t sk_flags; 143 uint8_t sk_flags;
144 struct sshbuf *sk_key_handle; 144 struct sshbuf *sk_key_handle;
@@ -180,6 +180,7 @@ int sshkey_unshield_private(struct sshkey *);
180 180
181int sshkey_type_from_name(const char *); 181int sshkey_type_from_name(const char *);
182int sshkey_is_cert(const struct sshkey *); 182int sshkey_is_cert(const struct sshkey *);
183int sshkey_is_sk(const struct sshkey *);
183int sshkey_type_is_cert(int); 184int sshkey_type_is_cert(int);
184int sshkey_type_plain(int); 185int sshkey_type_plain(int);
185int sshkey_to_certified(struct sshkey *); 186int sshkey_to_certified(struct sshkey *);