diff options
author | djm@openbsd.org <djm@openbsd.org> | 2019-10-31 21:23:19 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2019-11-01 09:46:10 +1100 |
commit | 9a14c64c38fc14d0029f1c7bc70cf62cc7f0fdf9 (patch) | |
tree | d79bb8d66eeba8e353f18dac919cb65d0ad896c7 | |
parent | 07da39f71d36fb547749a5b16aa8892e621a7e4a (diff) |
upstream: Refactor signing - use sshkey_sign for everything,
including the new U2F signatures.
Don't use sshsk_ecdsa_sign() directly, instead make it reachable via
sshkey_sign() like all other signature operations. This means that
we need to add a provider argument to sshkey_sign(), so most of this
change is mechanically adding that.
Suggested by / ok markus@
OpenBSD-Commit-ID: d5193a03fcfa895085d91b2b83d984a9fde76c8c
-rw-r--r-- | krl.c | 4 | ||||
-rw-r--r-- | monitor.c | 4 | ||||
-rw-r--r-- | monitor_wrap.c | 8 | ||||
-rw-r--r-- | monitor_wrap.h | 4 | ||||
-rw-r--r-- | ssh-agent.c | 7 | ||||
-rw-r--r-- | ssh-keygen.c | 18 | ||||
-rw-r--r-- | ssh-keysign.c | 6 | ||||
-rw-r--r-- | ssh_api.c | 9 | ||||
-rw-r--r-- | sshconnect2.c | 17 | ||||
-rw-r--r-- | sshd.c | 8 | ||||
-rw-r--r-- | sshkey.c | 26 | ||||
-rw-r--r-- | sshkey.h | 11 | ||||
-rw-r--r-- | sshsig.c | 21 | ||||
-rw-r--r-- | sshsig.h | 11 |
14 files changed, 82 insertions, 72 deletions
@@ -14,7 +14,7 @@ | |||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | /* $OpenBSD: krl.c,v 1.44 2019/09/06 04:53:27 djm Exp $ */ | 17 | /* $OpenBSD: krl.c,v 1.45 2019/10/31 21:23:19 djm Exp $ */ |
18 | 18 | ||
19 | #include "includes.h" | 19 | #include "includes.h" |
20 | 20 | ||
@@ -813,7 +813,7 @@ ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf, | |||
813 | goto out; | 813 | goto out; |
814 | 814 | ||
815 | if ((r = sshkey_sign(sign_keys[i], &sblob, &slen, | 815 | if ((r = sshkey_sign(sign_keys[i], &sblob, &slen, |
816 | sshbuf_ptr(buf), sshbuf_len(buf), NULL, 0)) != 0) | 816 | sshbuf_ptr(buf), sshbuf_len(buf), NULL, NULL, 0)) != 0) |
817 | goto out; | 817 | goto out; |
818 | KRL_DBG(("%s: signature sig len %zu", __func__, slen)); | 818 | KRL_DBG(("%s: signature sig len %zu", __func__, slen)); |
819 | if ((r = sshbuf_put_string(buf, sblob, slen)) != 0) | 819 | if ((r = sshbuf_put_string(buf, sblob, slen)) != 0) |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor.c,v 1.199 2019/10/07 23:10:38 djm Exp $ */ | 1 | /* $OpenBSD: monitor.c,v 1.200 2019/10/31 21:23:19 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> | 4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> |
@@ -678,7 +678,7 @@ mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m) | |||
678 | 678 | ||
679 | if ((key = get_hostkey_by_index(keyid)) != NULL) { | 679 | if ((key = get_hostkey_by_index(keyid)) != NULL) { |
680 | if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, alg, | 680 | if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, alg, |
681 | compat)) != 0) | 681 | NULL, compat)) != 0) |
682 | fatal("%s: sshkey_sign failed: %s", | 682 | fatal("%s: sshkey_sign failed: %s", |
683 | __func__, ssh_err(r)); | 683 | __func__, ssh_err(r)); |
684 | } else if ((key = get_hostkey_public_by_index(keyid, ssh)) != NULL && | 684 | } else if ((key = get_hostkey_public_by_index(keyid, ssh)) != NULL && |
diff --git a/monitor_wrap.c b/monitor_wrap.c index 4169b7604..d20dc5191 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor_wrap.c,v 1.113 2019/06/28 13:35:04 deraadt Exp $ */ | 1 | /* $OpenBSD: monitor_wrap.c,v 1.114 2019/10/31 21:23:19 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> | 4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> |
@@ -215,7 +215,8 @@ mm_choose_dh(int min, int nbits, int max) | |||
215 | 215 | ||
216 | int | 216 | int |
217 | mm_sshkey_sign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp, | 217 | mm_sshkey_sign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp, |
218 | const u_char *data, size_t datalen, const char *hostkey_alg, u_int compat) | 218 | const u_char *data, size_t datalen, const char *hostkey_alg, |
219 | const char *sk_provider, u_int compat) | ||
219 | { | 220 | { |
220 | struct kex *kex = *pmonitor->m_pkex; | 221 | struct kex *kex = *pmonitor->m_pkex; |
221 | struct sshbuf *m; | 222 | struct sshbuf *m; |
@@ -223,7 +224,8 @@ mm_sshkey_sign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp, | |||
223 | int r; | 224 | int r; |
224 | 225 | ||
225 | debug3("%s entering", __func__); | 226 | debug3("%s entering", __func__); |
226 | 227 | if (sk_provider != NULL) | |
228 | fatal("%s: sk_provider != NULL", __func__); | ||
227 | if ((m = sshbuf_new()) == NULL) | 229 | if ((m = sshbuf_new()) == NULL) |
228 | fatal("%s: sshbuf_new failed", __func__); | 230 | fatal("%s: sshbuf_new failed", __func__); |
229 | if ((r = sshbuf_put_u32(m, ndx)) != 0 || | 231 | if ((r = sshbuf_put_u32(m, ndx)) != 0 || |
diff --git a/monitor_wrap.h b/monitor_wrap.h index 191277f3a..76330fc60 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor_wrap.h,v 1.42 2019/09/06 05:23:55 djm Exp $ */ | 1 | /* $OpenBSD: monitor_wrap.h,v 1.43 2019/10/31 21:23:19 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 4 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
@@ -45,7 +45,7 @@ int mm_is_monitor(void); | |||
45 | DH *mm_choose_dh(int, int, int); | 45 | DH *mm_choose_dh(int, int, int); |
46 | #endif | 46 | #endif |
47 | int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *, | 47 | int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *, |
48 | const u_char *, size_t, const char *, u_int compat); | 48 | const u_char *, size_t, const char *, const char *, u_int compat); |
49 | void mm_inform_authserv(char *, char *); | 49 | void mm_inform_authserv(char *, char *); |
50 | struct passwd *mm_getpwnamallow(struct ssh *, const char *); | 50 | struct passwd *mm_getpwnamallow(struct ssh *, const char *); |
51 | char *mm_auth2_read_banner(void); | 51 | char *mm_auth2_read_banner(void); |
diff --git a/ssh-agent.c b/ssh-agent.c index 6bf9536fb..07f19c53a 100644 --- a/ssh-agent.c +++ b/ssh-agent.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-agent.c,v 1.238 2019/10/31 21:22:01 djm Exp $ */ | 1 | /* $OpenBSD: ssh-agent.c,v 1.239 2019/10/31 21:23:19 djm 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 |
@@ -430,12 +430,13 @@ process_sign_request2(SocketEntry *e) | |||
430 | if ((r = provider_sign(id->sk_provider, id->key, &signature, | 430 | if ((r = provider_sign(id->sk_provider, id->key, &signature, |
431 | &slen, data, dlen, agent_decode_alg(key, flags), | 431 | &slen, data, dlen, agent_decode_alg(key, flags), |
432 | compat)) != 0) { | 432 | compat)) != 0) { |
433 | error("%s: sshkey_sign: %s", __func__, ssh_err(r)); | 433 | error("%s: sign: %s", __func__, ssh_err(r)); |
434 | goto send; | 434 | goto send; |
435 | } | 435 | } |
436 | } else { | 436 | } else { |
437 | if ((r = sshkey_sign(id->key, &signature, &slen, | 437 | if ((r = sshkey_sign(id->key, &signature, &slen, |
438 | data, dlen, agent_decode_alg(key, flags), compat)) != 0) { | 438 | data, dlen, agent_decode_alg(key, flags), |
439 | NULL, compat)) != 0) { | ||
439 | error("%s: sshkey_sign: %s", __func__, ssh_err(r)); | 440 | error("%s: sshkey_sign: %s", __func__, ssh_err(r)); |
440 | goto send; | 441 | goto send; |
441 | } | 442 | } |
diff --git a/ssh-keygen.c b/ssh-keygen.c index ad7a2b4e0..14bf2560d 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-keygen.c,v 1.357 2019/10/31 21:17:09 djm Exp $ */ | 1 | /* $OpenBSD: ssh-keygen.c,v 1.358 2019/10/31 21:23:19 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 |
@@ -577,8 +577,10 @@ do_convert_private_ssh2(struct sshbuf *b) | |||
577 | error("%s: remaining bytes in key blob %d", __func__, rlen); | 577 | error("%s: remaining bytes in key blob %d", __func__, rlen); |
578 | 578 | ||
579 | /* try the key */ | 579 | /* try the key */ |
580 | if (sshkey_sign(key, &sig, &slen, data, sizeof(data), NULL, 0) != 0 || | 580 | if (sshkey_sign(key, &sig, &slen, data, sizeof(data), |
581 | sshkey_verify(key, sig, slen, data, sizeof(data), NULL, 0) != 0) { | 581 | NULL, NULL, 0) != 0 || |
582 | sshkey_verify(key, sig, slen, data, sizeof(data), | ||
583 | NULL, 0) != 0) { | ||
582 | sshkey_free(key); | 584 | sshkey_free(key); |
583 | free(sig); | 585 | free(sig); |
584 | return NULL; | 586 | return NULL; |
@@ -1709,7 +1711,7 @@ load_pkcs11_key(char *path) | |||
1709 | static int | 1711 | static int |
1710 | agent_signer(struct sshkey *key, u_char **sigp, size_t *lenp, | 1712 | agent_signer(struct sshkey *key, u_char **sigp, size_t *lenp, |
1711 | const u_char *data, size_t datalen, | 1713 | const u_char *data, size_t datalen, |
1712 | const char *alg, u_int compat, void *ctx) | 1714 | const char *alg, const char *sk_provider, u_int compat, void *ctx) |
1713 | { | 1715 | { |
1714 | int *agent_fdp = (int *)ctx; | 1716 | int *agent_fdp = (int *)ctx; |
1715 | 1717 | ||
@@ -1821,11 +1823,13 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent, | |||
1821 | 1823 | ||
1822 | if (agent_fd != -1 && (ca->flags & SSHKEY_FLAG_EXT) != 0) { | 1824 | if (agent_fd != -1 && (ca->flags & SSHKEY_FLAG_EXT) != 0) { |
1823 | if ((r = sshkey_certify_custom(public, ca, | 1825 | if ((r = sshkey_certify_custom(public, ca, |
1824 | key_type_name, agent_signer, &agent_fd)) != 0) | 1826 | key_type_name, sk_provider, agent_signer, |
1827 | &agent_fd)) != 0) | ||
1825 | fatal("Couldn't certify key %s via agent: %s", | 1828 | fatal("Couldn't certify key %s via agent: %s", |
1826 | tmp, ssh_err(r)); | 1829 | tmp, ssh_err(r)); |
1827 | } else { | 1830 | } else { |
1828 | if ((sshkey_certify(public, ca, key_type_name)) != 0) | 1831 | if ((sshkey_certify(public, ca, key_type_name, |
1832 | sk_provider)) != 0) | ||
1829 | fatal("Couldn't certify key %s: %s", | 1833 | fatal("Couldn't certify key %s: %s", |
1830 | tmp, ssh_err(r)); | 1834 | tmp, ssh_err(r)); |
1831 | } | 1835 | } |
@@ -2507,7 +2511,7 @@ sign_one(struct sshkey *signkey, const char *filename, int fd, | |||
2507 | else | 2511 | else |
2508 | fprintf(stderr, "Signing file %s\n", filename); | 2512 | fprintf(stderr, "Signing file %s\n", filename); |
2509 | } | 2513 | } |
2510 | if ((r = sshsig_sign_fd(signkey, NULL, fd, sig_namespace, | 2514 | if ((r = sshsig_sign_fd(signkey, NULL, sk_provider, fd, sig_namespace, |
2511 | &sigbuf, signer, signer_ctx)) != 0) { | 2515 | &sigbuf, signer, signer_ctx)) != 0) { |
2512 | error("Signing %s failed: %s", filename, ssh_err(r)); | 2516 | error("Signing %s failed: %s", filename, ssh_err(r)); |
2513 | goto out; | 2517 | goto out; |
diff --git a/ssh-keysign.c b/ssh-keysign.c index 6cfd5b46c..d6aa6361d 100644 --- a/ssh-keysign.c +++ b/ssh-keysign.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-keysign.c,v 1.61 2019/10/02 00:42:30 djm Exp $ */ | 1 | /* $OpenBSD: ssh-keysign.c,v 1.62 2019/10/31 21:23:19 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2002 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2002 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -277,8 +277,8 @@ main(int argc, char **argv) | |||
277 | sshkey_type(key), fp ? fp : ""); | 277 | sshkey_type(key), fp ? fp : ""); |
278 | } | 278 | } |
279 | 279 | ||
280 | if ((r = sshkey_sign(keys[i], &signature, &slen, data, dlen, NULL, 0)) | 280 | if ((r = sshkey_sign(keys[i], &signature, &slen, data, dlen, |
281 | != 0) | 281 | NULL, NULL, 0)) != 0) |
282 | fatal("sshkey_sign failed: %s", ssh_err(r)); | 282 | fatal("sshkey_sign failed: %s", ssh_err(r)); |
283 | free(data); | 283 | free(data); |
284 | 284 | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh_api.c,v 1.18 2019/09/13 04:36:43 dtucker Exp $ */ | 1 | /* $OpenBSD: ssh_api.c,v 1.19 2019/10/31 21:23:19 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2012 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2012 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -54,7 +54,7 @@ int _ssh_host_key_sign(struct ssh *, struct sshkey *, struct sshkey *, | |||
54 | */ | 54 | */ |
55 | int use_privsep = 0; | 55 | int use_privsep = 0; |
56 | int mm_sshkey_sign(struct sshkey *, u_char **, u_int *, | 56 | int mm_sshkey_sign(struct sshkey *, u_char **, u_int *, |
57 | u_char *, u_int, char *, u_int); | 57 | const u_char *, u_int, const char *, const char *, u_int); |
58 | 58 | ||
59 | #ifdef WITH_OPENSSL | 59 | #ifdef WITH_OPENSSL |
60 | DH *mm_choose_dh(int, int, int); | 60 | DH *mm_choose_dh(int, int, int); |
@@ -66,7 +66,8 @@ u_int session_id2_len = 0; | |||
66 | 66 | ||
67 | int | 67 | int |
68 | mm_sshkey_sign(struct sshkey *key, u_char **sigp, u_int *lenp, | 68 | mm_sshkey_sign(struct sshkey *key, u_char **sigp, u_int *lenp, |
69 | u_char *data, u_int datalen, char *alg, u_int compat) | 69 | const u_char *data, u_int datalen, const char *alg, const char *sk_provider, |
70 | u_int compat) | ||
70 | { | 71 | { |
71 | return (-1); | 72 | return (-1); |
72 | } | 73 | } |
@@ -568,5 +569,5 @@ _ssh_host_key_sign(struct ssh *ssh, struct sshkey *privkey, | |||
568 | const u_char *data, size_t dlen, const char *alg) | 569 | const u_char *data, size_t dlen, const char *alg) |
569 | { | 570 | { |
570 | return sshkey_sign(privkey, signature, slen, data, dlen, | 571 | return sshkey_sign(privkey, signature, slen, data, dlen, |
571 | alg, ssh->compat); | 572 | alg, NULL, ssh->compat); |
572 | } | 573 | } |
diff --git a/sshconnect2.c b/sshconnect2.c index 62f0c3e76..867d463d6 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect2.c,v 1.309 2019/10/31 21:18:28 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect2.c,v 1.310 2019/10/31 21:23:19 djm 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. |
@@ -1178,19 +1178,8 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp, | |||
1178 | } | 1178 | } |
1179 | sign_key = prv; | 1179 | sign_key = prv; |
1180 | } | 1180 | } |
1181 | 1181 | if ((r = sshkey_sign(sign_key, sigp, lenp, data, datalen, | |
1182 | if (sshkey_type_plain(sign_key->type) == KEY_ECDSA_SK) { | 1182 | alg, options.sk_provider, compat)) != 0) { |
1183 | if (options.sk_provider == NULL) { | ||
1184 | /* Shouldn't happen here; checked in pubkey_prepare() */ | ||
1185 | fatal("%s: missing SecurityKeyProvider", __func__); | ||
1186 | } | ||
1187 | if ((r = sshsk_ecdsa_sign(options.sk_provider, sign_key, | ||
1188 | sigp, lenp, data, datalen, compat)) != 0) { | ||
1189 | debug("%s: sshsk_ecdsa_sign: %s", __func__, ssh_err(r)); | ||
1190 | goto out; | ||
1191 | } | ||
1192 | } else if ((r = sshkey_sign(sign_key, sigp, lenp, data, datalen, | ||
1193 | alg, compat)) != 0) { | ||
1194 | debug("%s: sshkey_sign: %s", __func__, ssh_err(r)); | 1183 | debug("%s: sshkey_sign: %s", __func__, ssh_err(r)); |
1195 | goto out; | 1184 | goto out; |
1196 | } | 1185 | } |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.538 2019/10/29 07:47:27 dtucker Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.539 2019/10/31 21:23:19 djm 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 |
@@ -2209,17 +2209,17 @@ sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey, | |||
2209 | if (use_privsep) { | 2209 | if (use_privsep) { |
2210 | if (privkey) { | 2210 | if (privkey) { |
2211 | if (mm_sshkey_sign(ssh, privkey, signature, slenp, | 2211 | if (mm_sshkey_sign(ssh, privkey, signature, slenp, |
2212 | data, dlen, alg, ssh->compat) < 0) | 2212 | data, dlen, alg, NULL, ssh->compat) < 0) |
2213 | fatal("%s: privkey sign failed", __func__); | 2213 | fatal("%s: privkey sign failed", __func__); |
2214 | } else { | 2214 | } else { |
2215 | if (mm_sshkey_sign(ssh, pubkey, signature, slenp, | 2215 | if (mm_sshkey_sign(ssh, pubkey, signature, slenp, |
2216 | data, dlen, alg, ssh->compat) < 0) | 2216 | data, dlen, alg, NULL, ssh->compat) < 0) |
2217 | fatal("%s: pubkey sign failed", __func__); | 2217 | fatal("%s: pubkey sign failed", __func__); |
2218 | } | 2218 | } |
2219 | } else { | 2219 | } else { |
2220 | if (privkey) { | 2220 | if (privkey) { |
2221 | if (sshkey_sign(privkey, signature, slenp, data, dlen, | 2221 | if (sshkey_sign(privkey, signature, slenp, data, dlen, |
2222 | alg, ssh->compat) < 0) | 2222 | alg, NULL, ssh->compat) < 0) |
2223 | fatal("%s: privkey sign failed", __func__); | 2223 | fatal("%s: privkey sign failed", __func__); |
2224 | } else { | 2224 | } else { |
2225 | if ((r = ssh_agent_sign(auth_sock, pubkey, | 2225 | if ((r = ssh_agent_sign(auth_sock, pubkey, |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshkey.c,v 1.85 2019/10/31 21:15:14 djm Exp $ */ | 1 | /* $OpenBSD: sshkey.c,v 1.86 2019/10/31 21:23:19 djm 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. |
@@ -57,6 +57,7 @@ | |||
57 | #define SSHKEY_INTERNAL | 57 | #define SSHKEY_INTERNAL |
58 | #include "sshkey.h" | 58 | #include "sshkey.h" |
59 | #include "match.h" | 59 | #include "match.h" |
60 | #include "ssh-sk.h" | ||
60 | 61 | ||
61 | #ifdef WITH_XMSS | 62 | #ifdef WITH_XMSS |
62 | #include "sshkey-xmss.h" | 63 | #include "sshkey-xmss.h" |
@@ -2658,7 +2659,8 @@ sshkey_check_sigtype(const u_char *sig, size_t siglen, | |||
2658 | int | 2659 | int |
2659 | sshkey_sign(struct sshkey *key, | 2660 | sshkey_sign(struct sshkey *key, |
2660 | u_char **sigp, size_t *lenp, | 2661 | u_char **sigp, size_t *lenp, |
2661 | const u_char *data, size_t datalen, const char *alg, u_int compat) | 2662 | const u_char *data, size_t datalen, |
2663 | const char *alg, const char *sk_provider, u_int compat) | ||
2662 | { | 2664 | { |
2663 | int was_shielded = sshkey_is_shielded(key); | 2665 | int was_shielded = sshkey_is_shielded(key); |
2664 | int r2, r = SSH_ERR_INTERNAL_ERROR; | 2666 | int r2, r = SSH_ERR_INTERNAL_ERROR; |
@@ -2682,6 +2684,11 @@ sshkey_sign(struct sshkey *key, | |||
2682 | case KEY_ECDSA: | 2684 | case KEY_ECDSA: |
2683 | r = ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat); | 2685 | r = ssh_ecdsa_sign(key, sigp, lenp, data, datalen, compat); |
2684 | break; | 2686 | break; |
2687 | case KEY_ECDSA_SK_CERT: | ||
2688 | case KEY_ECDSA_SK: | ||
2689 | r = sshsk_ecdsa_sign(sk_provider, key, sigp, lenp, | ||
2690 | data, datalen, compat); | ||
2691 | break; | ||
2685 | # endif /* OPENSSL_HAS_ECC */ | 2692 | # endif /* OPENSSL_HAS_ECC */ |
2686 | case KEY_RSA_CERT: | 2693 | case KEY_RSA_CERT: |
2687 | case KEY_RSA: | 2694 | case KEY_RSA: |
@@ -2802,7 +2809,7 @@ sshkey_drop_cert(struct sshkey *k) | |||
2802 | /* Sign a certified key, (re-)generating the signed certblob. */ | 2809 | /* Sign a certified key, (re-)generating the signed certblob. */ |
2803 | int | 2810 | int |
2804 | sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg, | 2811 | sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg, |
2805 | sshkey_certify_signer *signer, void *signer_ctx) | 2812 | const char *sk_provider, sshkey_certify_signer *signer, void *signer_ctx) |
2806 | { | 2813 | { |
2807 | struct sshbuf *principals = NULL; | 2814 | struct sshbuf *principals = NULL; |
2808 | u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32]; | 2815 | u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32]; |
@@ -2934,7 +2941,7 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg, | |||
2934 | 2941 | ||
2935 | /* Sign the whole mess */ | 2942 | /* Sign the whole mess */ |
2936 | if ((ret = signer(ca, &sig_blob, &sig_len, sshbuf_ptr(cert), | 2943 | if ((ret = signer(ca, &sig_blob, &sig_len, sshbuf_ptr(cert), |
2937 | sshbuf_len(cert), alg, 0, signer_ctx)) != 0) | 2944 | sshbuf_len(cert), alg, sk_provider, 0, signer_ctx)) != 0) |
2938 | goto out; | 2945 | goto out; |
2939 | /* Check and update signature_type against what was actually used */ | 2946 | /* Check and update signature_type against what was actually used */ |
2940 | if ((ret = sshkey_get_sigtype(sig_blob, sig_len, &sigtype)) != 0) | 2947 | if ((ret = sshkey_get_sigtype(sig_blob, sig_len, &sigtype)) != 0) |
@@ -2964,17 +2971,20 @@ sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg, | |||
2964 | static int | 2971 | static int |
2965 | default_key_sign(struct sshkey *key, u_char **sigp, size_t *lenp, | 2972 | default_key_sign(struct sshkey *key, u_char **sigp, size_t *lenp, |
2966 | const u_char *data, size_t datalen, | 2973 | const u_char *data, size_t datalen, |
2967 | const char *alg, u_int compat, void *ctx) | 2974 | const char *alg, const char *sk_provider, u_int compat, void *ctx) |
2968 | { | 2975 | { |
2969 | if (ctx != NULL) | 2976 | if (ctx != NULL) |
2970 | return SSH_ERR_INVALID_ARGUMENT; | 2977 | return SSH_ERR_INVALID_ARGUMENT; |
2971 | return sshkey_sign(key, sigp, lenp, data, datalen, alg, compat); | 2978 | return sshkey_sign(key, sigp, lenp, data, datalen, alg, |
2979 | sk_provider, compat); | ||
2972 | } | 2980 | } |
2973 | 2981 | ||
2974 | int | 2982 | int |
2975 | sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg) | 2983 | sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg, |
2984 | const char *sk_provider) | ||
2976 | { | 2985 | { |
2977 | return sshkey_certify_custom(k, ca, alg, default_key_sign, NULL); | 2986 | return sshkey_certify_custom(k, ca, alg, sk_provider, |
2987 | default_key_sign, NULL); | ||
2978 | } | 2988 | } |
2979 | 2989 | ||
2980 | int | 2990 | int |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshkey.h,v 1.35 2019/10/31 21:15:14 djm Exp $ */ | 1 | /* $OpenBSD: sshkey.h,v 1.36 2019/10/31 21:23:19 djm 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. |
@@ -189,12 +189,13 @@ size_t sshkey_format_cert_validity(const struct sshkey_cert *, | |||
189 | char *, size_t) __attribute__((__bounded__(__string__, 2, 3))); | 189 | char *, size_t) __attribute__((__bounded__(__string__, 2, 3))); |
190 | int sshkey_check_cert_sigtype(const struct sshkey *, const char *); | 190 | int sshkey_check_cert_sigtype(const struct sshkey *, const char *); |
191 | 191 | ||
192 | int sshkey_certify(struct sshkey *, struct sshkey *, const char *); | 192 | int sshkey_certify(struct sshkey *, struct sshkey *, |
193 | const char *, const char *); | ||
193 | /* Variant allowing use of a custom signature function (e.g. for ssh-agent) */ | 194 | /* Variant allowing use of a custom signature function (e.g. for ssh-agent) */ |
194 | typedef int sshkey_certify_signer(struct sshkey *, u_char **, size_t *, | 195 | typedef int sshkey_certify_signer(struct sshkey *, u_char **, size_t *, |
195 | const u_char *, size_t, const char *, u_int, void *); | 196 | const u_char *, size_t, const char *, const char *, u_int, void *); |
196 | int sshkey_certify_custom(struct sshkey *, struct sshkey *, const char *, | 197 | int sshkey_certify_custom(struct sshkey *, struct sshkey *, const char *, |
197 | sshkey_certify_signer *, void *); | 198 | const char *, sshkey_certify_signer *, void *); |
198 | 199 | ||
199 | int sshkey_ecdsa_nid_from_name(const char *); | 200 | int sshkey_ecdsa_nid_from_name(const char *); |
200 | int sshkey_curve_name_to_nid(const char *); | 201 | int sshkey_curve_name_to_nid(const char *); |
@@ -223,7 +224,7 @@ int sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *); | |||
223 | int sshkey_putb_plain(const struct sshkey *, struct sshbuf *); | 224 | int sshkey_putb_plain(const struct sshkey *, struct sshbuf *); |
224 | 225 | ||
225 | int sshkey_sign(struct sshkey *, u_char **, size_t *, | 226 | int sshkey_sign(struct sshkey *, u_char **, size_t *, |
226 | const u_char *, size_t, const char *, u_int); | 227 | const u_char *, size_t, const char *, const char *, u_int); |
227 | int sshkey_verify(const struct sshkey *, const u_char *, size_t, | 228 | int sshkey_verify(const struct sshkey *, const u_char *, size_t, |
228 | const u_char *, size_t, const char *, u_int); | 229 | const u_char *, size_t, const char *, u_int); |
229 | int sshkey_check_sigtype(const u_char *, size_t, const char *); | 230 | int sshkey_check_sigtype(const u_char *, size_t, const char *); |
@@ -151,8 +151,9 @@ done: | |||
151 | 151 | ||
152 | static int | 152 | static int |
153 | sshsig_wrap_sign(struct sshkey *key, const char *hashalg, | 153 | sshsig_wrap_sign(struct sshkey *key, const char *hashalg, |
154 | const struct sshbuf *h_message, const char *sig_namespace, | 154 | const char *sk_provider, const struct sshbuf *h_message, |
155 | struct sshbuf **out, sshsig_signer *signer, void *signer_ctx) | 155 | const char *sig_namespace, struct sshbuf **out, |
156 | sshsig_signer *signer, void *signer_ctx) | ||
156 | { | 157 | { |
157 | int r; | 158 | int r; |
158 | size_t slen = 0; | 159 | size_t slen = 0; |
@@ -184,14 +185,14 @@ sshsig_wrap_sign(struct sshkey *key, const char *hashalg, | |||
184 | if (signer != NULL) { | 185 | if (signer != NULL) { |
185 | if ((r = signer(key, &sig, &slen, | 186 | if ((r = signer(key, &sig, &slen, |
186 | sshbuf_ptr(tosign), sshbuf_len(tosign), | 187 | sshbuf_ptr(tosign), sshbuf_len(tosign), |
187 | sign_alg, 0, signer_ctx)) != 0) { | 188 | sign_alg, sk_provider, 0, signer_ctx)) != 0) { |
188 | error("Couldn't sign message: %s", ssh_err(r)); | 189 | error("Couldn't sign message: %s", ssh_err(r)); |
189 | goto done; | 190 | goto done; |
190 | } | 191 | } |
191 | } else { | 192 | } else { |
192 | if ((r = sshkey_sign(key, &sig, &slen, | 193 | if ((r = sshkey_sign(key, &sig, &slen, |
193 | sshbuf_ptr(tosign), sshbuf_len(tosign), | 194 | sshbuf_ptr(tosign), sshbuf_len(tosign), |
194 | sign_alg, 0)) != 0) { | 195 | sign_alg, sk_provider, 0)) != 0) { |
195 | error("Couldn't sign message: %s", ssh_err(r)); | 196 | error("Couldn't sign message: %s", ssh_err(r)); |
196 | goto done; | 197 | goto done; |
197 | } | 198 | } |
@@ -425,7 +426,7 @@ hash_buffer(const struct sshbuf *m, const char *hashalg, struct sshbuf **bp) | |||
425 | } | 426 | } |
426 | 427 | ||
427 | int | 428 | int |
428 | sshsig_signb(struct sshkey *key, const char *hashalg, | 429 | sshsig_signb(struct sshkey *key, const char *hashalg, const char *sk_provider, |
429 | const struct sshbuf *message, const char *sig_namespace, | 430 | const struct sshbuf *message, const char *sig_namespace, |
430 | struct sshbuf **out, sshsig_signer *signer, void *signer_ctx) | 431 | struct sshbuf **out, sshsig_signer *signer, void *signer_ctx) |
431 | { | 432 | { |
@@ -440,8 +441,8 @@ sshsig_signb(struct sshkey *key, const char *hashalg, | |||
440 | error("%s: hash_buffer failed: %s", __func__, ssh_err(r)); | 441 | error("%s: hash_buffer failed: %s", __func__, ssh_err(r)); |
441 | goto out; | 442 | goto out; |
442 | } | 443 | } |
443 | if ((r = sshsig_wrap_sign(key, hashalg, b, sig_namespace, out, | 444 | if ((r = sshsig_wrap_sign(key, hashalg, sk_provider, b, |
444 | signer, signer_ctx)) != 0) | 445 | sig_namespace, out, signer, signer_ctx)) != 0) |
445 | goto out; | 446 | goto out; |
446 | /* success */ | 447 | /* success */ |
447 | r = 0; | 448 | r = 0; |
@@ -551,7 +552,7 @@ hash_file(int fd, const char *hashalg, struct sshbuf **bp) | |||
551 | } | 552 | } |
552 | 553 | ||
553 | int | 554 | int |
554 | sshsig_sign_fd(struct sshkey *key, const char *hashalg, | 555 | sshsig_sign_fd(struct sshkey *key, const char *hashalg, const char *sk_provider, |
555 | int fd, const char *sig_namespace, struct sshbuf **out, | 556 | int fd, const char *sig_namespace, struct sshbuf **out, |
556 | sshsig_signer *signer, void *signer_ctx) | 557 | sshsig_signer *signer, void *signer_ctx) |
557 | { | 558 | { |
@@ -566,8 +567,8 @@ sshsig_sign_fd(struct sshkey *key, const char *hashalg, | |||
566 | error("%s: hash_file failed: %s", __func__, ssh_err(r)); | 567 | error("%s: hash_file failed: %s", __func__, ssh_err(r)); |
567 | return r; | 568 | return r; |
568 | } | 569 | } |
569 | if ((r = sshsig_wrap_sign(key, hashalg, b, sig_namespace, out, | 570 | if ((r = sshsig_wrap_sign(key, hashalg, sk_provider, b, |
570 | signer, signer_ctx)) != 0) | 571 | sig_namespace, out, signer, signer_ctx)) != 0) |
571 | goto out; | 572 | goto out; |
572 | /* success */ | 573 | /* success */ |
573 | r = 0; | 574 | r = 0; |
@@ -22,7 +22,7 @@ struct sshkey; | |||
22 | struct sshsigopt; | 22 | struct sshsigopt; |
23 | 23 | ||
24 | typedef int sshsig_signer(struct sshkey *, u_char **, size_t *, | 24 | typedef int sshsig_signer(struct sshkey *, u_char **, size_t *, |
25 | const u_char *, size_t, const char *, u_int, void *); | 25 | const u_char *, size_t, const char *, const char *, u_int, void *); |
26 | 26 | ||
27 | /* Buffer-oriented API */ | 27 | /* Buffer-oriented API */ |
28 | 28 | ||
@@ -32,8 +32,9 @@ typedef int sshsig_signer(struct sshkey *, u_char **, size_t *, | |||
32 | * out is populated with the detached signature, or NULL on failure. | 32 | * out is populated with the detached signature, or NULL on failure. |
33 | */ | 33 | */ |
34 | int sshsig_signb(struct sshkey *key, const char *hashalg, | 34 | int sshsig_signb(struct sshkey *key, const char *hashalg, |
35 | const struct sshbuf *message, const char *sig_namespace, | 35 | const char *sk_provider, const struct sshbuf *message, |
36 | struct sshbuf **out, sshsig_signer *signer, void *signer_ctx); | 36 | const char *sig_namespace, struct sshbuf **out, |
37 | sshsig_signer *signer, void *signer_ctx); | ||
37 | 38 | ||
38 | /* | 39 | /* |
39 | * Verifies that a detached signature is valid and optionally returns key | 40 | * Verifies that a detached signature is valid and optionally returns key |
@@ -52,8 +53,8 @@ int sshsig_verifyb(struct sshbuf *signature, | |||
52 | * out is populated with the detached signature, or NULL on failure. | 53 | * out is populated with the detached signature, or NULL on failure. |
53 | */ | 54 | */ |
54 | int sshsig_sign_fd(struct sshkey *key, const char *hashalg, | 55 | int sshsig_sign_fd(struct sshkey *key, const char *hashalg, |
55 | int fd, const char *sig_namespace, struct sshbuf **out, | 56 | const char *sk_provider, int fd, const char *sig_namespace, |
56 | sshsig_signer *signer, void *signer_ctx); | 57 | struct sshbuf **out, sshsig_signer *signer, void *signer_ctx); |
57 | 58 | ||
58 | /* | 59 | /* |
59 | * Verifies that a detached signature over a file is valid and optionally | 60 | * Verifies that a detached signature over a file is valid and optionally |