diff options
-rw-r--r-- | authfd.c | 4 | ||||
-rw-r--r-- | myproposal.h | 4 | ||||
-rw-r--r-- | pathnames.h | 3 | ||||
-rw-r--r-- | readconf.c | 4 | ||||
-rw-r--r-- | ssh-add.c | 5 | ||||
-rw-r--r-- | ssh-agent.c | 4 | ||||
-rw-r--r-- | ssh-keygen.c | 25 | ||||
-rw-r--r-- | ssh-sk-helper.c | 4 | ||||
-rw-r--r-- | sshconnect.c | 4 | ||||
-rw-r--r-- | sshconnect2.c | 13 | ||||
-rw-r--r-- | sshkey.c | 154 | ||||
-rw-r--r-- | sshkey.h | 7 |
12 files changed, 200 insertions, 31 deletions
@@ -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) |
@@ -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]); |
@@ -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 | ||
378 | int | ||
379 | sshkey_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 */ |
372 | int | 393 | int |
373 | sshkey_type_plain(int type) | 394 | sshkey_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 */ |
@@ -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 | ||
181 | int sshkey_type_from_name(const char *); | 181 | int sshkey_type_from_name(const char *); |
182 | int sshkey_is_cert(const struct sshkey *); | 182 | int sshkey_is_cert(const struct sshkey *); |
183 | int sshkey_is_sk(const struct sshkey *); | ||
183 | int sshkey_type_is_cert(int); | 184 | int sshkey_type_is_cert(int); |
184 | int sshkey_type_plain(int); | 185 | int sshkey_type_plain(int); |
185 | int sshkey_to_certified(struct sshkey *); | 186 | int sshkey_to_certified(struct sshkey *); |