summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2019-10-31 21:23:19 +0000
committerDamien Miller <djm@mindrot.org>2019-11-01 09:46:10 +1100
commit9a14c64c38fc14d0029f1c7bc70cf62cc7f0fdf9 (patch)
treed79bb8d66eeba8e353f18dac919cb65d0ad896c7
parent07da39f71d36fb547749a5b16aa8892e621a7e4a (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.c4
-rw-r--r--monitor.c4
-rw-r--r--monitor_wrap.c8
-rw-r--r--monitor_wrap.h4
-rw-r--r--ssh-agent.c7
-rw-r--r--ssh-keygen.c18
-rw-r--r--ssh-keysign.c6
-rw-r--r--ssh_api.c9
-rw-r--r--sshconnect2.c17
-rw-r--r--sshd.c8
-rw-r--r--sshkey.c26
-rw-r--r--sshkey.h11
-rw-r--r--sshsig.c21
-rw-r--r--sshsig.h11
14 files changed, 82 insertions, 72 deletions
diff --git a/krl.c b/krl.c
index a7f690955..89cb433bd 100644
--- a/krl.c
+++ b/krl.c
@@ -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)
diff --git a/monitor.c b/monitor.c
index 00af44f98..a884d5f9d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -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
216int 216int
217mm_sshkey_sign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp, 217mm_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);
45DH *mm_choose_dh(int, int, int); 45DH *mm_choose_dh(int, int, int);
46#endif 46#endif
47int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *, 47int 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);
49void mm_inform_authserv(char *, char *); 49void mm_inform_authserv(char *, char *);
50struct passwd *mm_getpwnamallow(struct ssh *, const char *); 50struct passwd *mm_getpwnamallow(struct ssh *, const char *);
51char *mm_auth2_read_banner(void); 51char *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)
1709static int 1711static int
1710agent_signer(struct sshkey *key, u_char **sigp, size_t *lenp, 1712agent_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
diff --git a/ssh_api.c b/ssh_api.c
index 03dac0982..e0b195521 100644
--- a/ssh_api.c
+++ b/ssh_api.c
@@ -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 */
55int use_privsep = 0; 55int use_privsep = 0;
56int mm_sshkey_sign(struct sshkey *, u_char **, u_int *, 56int 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
60DH *mm_choose_dh(int, int, int); 60DH *mm_choose_dh(int, int, int);
@@ -66,7 +66,8 @@ u_int session_id2_len = 0;
66 66
67int 67int
68mm_sshkey_sign(struct sshkey *key, u_char **sigp, u_int *lenp, 68mm_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 }
diff --git a/sshd.c b/sshd.c
index cf7af1c61..e782a99f2 100644
--- a/sshd.c
+++ b/sshd.c
@@ -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,
diff --git a/sshkey.c b/sshkey.c
index d87fee8ee..4744dfbef 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -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,
2658int 2659int
2659sshkey_sign(struct sshkey *key, 2660sshkey_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. */
2803int 2810int
2804sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg, 2811sshkey_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,
2964static int 2971static int
2965default_key_sign(struct sshkey *key, u_char **sigp, size_t *lenp, 2972default_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
2974int 2982int
2975sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg) 2983sshkey_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
2980int 2990int
diff --git a/sshkey.h b/sshkey.h
index 2edcb13ab..1d36a24a9 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -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)));
190int sshkey_check_cert_sigtype(const struct sshkey *, const char *); 190int sshkey_check_cert_sigtype(const struct sshkey *, const char *);
191 191
192int sshkey_certify(struct sshkey *, struct sshkey *, const char *); 192int 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) */
194typedef int sshkey_certify_signer(struct sshkey *, u_char **, size_t *, 195typedef 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 *);
196int sshkey_certify_custom(struct sshkey *, struct sshkey *, const char *, 197int sshkey_certify_custom(struct sshkey *, struct sshkey *, const char *,
197 sshkey_certify_signer *, void *); 198 const char *, sshkey_certify_signer *, void *);
198 199
199int sshkey_ecdsa_nid_from_name(const char *); 200int sshkey_ecdsa_nid_from_name(const char *);
200int sshkey_curve_name_to_nid(const char *); 201int sshkey_curve_name_to_nid(const char *);
@@ -223,7 +224,7 @@ int sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *);
223int sshkey_putb_plain(const struct sshkey *, struct sshbuf *); 224int sshkey_putb_plain(const struct sshkey *, struct sshbuf *);
224 225
225int sshkey_sign(struct sshkey *, u_char **, size_t *, 226int 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);
227int sshkey_verify(const struct sshkey *, const u_char *, size_t, 228int 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);
229int sshkey_check_sigtype(const u_char *, size_t, const char *); 230int sshkey_check_sigtype(const u_char *, size_t, const char *);
diff --git a/sshsig.c b/sshsig.c
index b19cd077d..8c7aba1b9 100644
--- a/sshsig.c
+++ b/sshsig.c
@@ -151,8 +151,9 @@ done:
151 151
152static int 152static int
153sshsig_wrap_sign(struct sshkey *key, const char *hashalg, 153sshsig_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
427int 428int
428sshsig_signb(struct sshkey *key, const char *hashalg, 429sshsig_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
553int 554int
554sshsig_sign_fd(struct sshkey *key, const char *hashalg, 555sshsig_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;
diff --git a/sshsig.h b/sshsig.h
index e3eeb601b..487db116c 100644
--- a/sshsig.h
+++ b/sshsig.h
@@ -22,7 +22,7 @@ struct sshkey;
22struct sshsigopt; 22struct sshsigopt;
23 23
24typedef int sshsig_signer(struct sshkey *, u_char **, size_t *, 24typedef 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 */
34int sshsig_signb(struct sshkey *key, const char *hashalg, 34int 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 */
54int sshsig_sign_fd(struct sshkey *key, const char *hashalg, 55int 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