summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--auth2-hostbased.c4
-rw-r--r--auth2-pubkey.c11
-rw-r--r--clientloop.c5
-rw-r--r--kexgen.c4
-rw-r--r--kexgexc.c4
-rw-r--r--krl.c4
-rw-r--r--monitor.c14
-rw-r--r--monitor_wrap.c23
-rw-r--r--monitor_wrap.h5
-rw-r--r--ssh-add.c4
-rw-r--r--ssh-ecdsa-sk.c21
-rw-r--r--ssh-ed25519-sk.c20
-rw-r--r--ssh-keygen.c13
-rw-r--r--sshkey.c19
-rw-r--r--sshkey.h18
-rw-r--r--sshsig.c22
-rw-r--r--sshsig.h6
17 files changed, 147 insertions, 50 deletions
diff --git a/auth2-hostbased.c b/auth2-hostbased.c
index d46047084..5e9b7c65d 100644
--- a/auth2-hostbased.c
+++ b/auth2-hostbased.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-hostbased.c,v 1.41 2019/09/06 04:53:27 djm Exp $ */ 1/* $OpenBSD: auth2-hostbased.c,v 1.42 2019/11/25 00:51:37 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -151,7 +151,7 @@ userauth_hostbased(struct ssh *ssh)
151 if (PRIVSEP(hostbased_key_allowed(ssh, authctxt->pw, cuser, 151 if (PRIVSEP(hostbased_key_allowed(ssh, authctxt->pw, cuser,
152 chost, key)) && 152 chost, key)) &&
153 PRIVSEP(sshkey_verify(key, sig, slen, 153 PRIVSEP(sshkey_verify(key, sig, slen,
154 sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat)) == 0) 154 sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat, NULL)) == 0)
155 authenticated = 1; 155 authenticated = 1;
156 156
157 auth2_record_key(authctxt, authenticated, key); 157 auth2_record_key(authctxt, authenticated, key);
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index df12c2c60..2b6986709 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-pubkey.c,v 1.94 2019/09/06 04:53:27 djm Exp $ */ 1/* $OpenBSD: auth2-pubkey.c,v 1.95 2019/11/25 00:51:37 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -98,6 +98,7 @@ userauth_pubkey(struct ssh *ssh)
98 int r, pktype; 98 int r, pktype;
99 int authenticated = 0; 99 int authenticated = 0;
100 struct sshauthopt *authopts = NULL; 100 struct sshauthopt *authopts = NULL;
101 struct sshkey_sig_details *sig_details = NULL;
101 102
102 if ((r = sshpkt_get_u8(ssh, &have_sig)) != 0 || 103 if ((r = sshpkt_get_u8(ssh, &have_sig)) != 0 ||
103 (r = sshpkt_get_cstring(ssh, &pkalg, NULL)) != 0 || 104 (r = sshpkt_get_cstring(ssh, &pkalg, NULL)) != 0 ||
@@ -213,9 +214,14 @@ userauth_pubkey(struct ssh *ssh)
213 PRIVSEP(sshkey_verify(key, sig, slen, 214 PRIVSEP(sshkey_verify(key, sig, slen,
214 sshbuf_ptr(b), sshbuf_len(b), 215 sshbuf_ptr(b), sshbuf_len(b),
215 (ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL, 216 (ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL,
216 ssh->compat)) == 0) { 217 ssh->compat, &sig_details)) == 0) {
217 authenticated = 1; 218 authenticated = 1;
218 } 219 }
220 if (sig_details != NULL) {
221 debug("%s: sk_counter = %u, sk_flags = 0x%02x",
222 __func__, sig_details->sk_counter,
223 sig_details->sk_flags);
224 }
219 auth2_record_key(authctxt, authenticated, key); 225 auth2_record_key(authctxt, authenticated, key);
220 } else { 226 } else {
221 debug("%s: test pkalg %s pkblob %s%s%s", 227 debug("%s: test pkalg %s pkblob %s%s%s",
@@ -266,6 +272,7 @@ done:
266 free(key_s); 272 free(key_s);
267 free(ca_s); 273 free(ca_s);
268 free(sig); 274 free(sig);
275 sshkey_sig_details_free(sig_details);
269 return authenticated; 276 return authenticated;
270} 277}
271 278
diff --git a/clientloop.c b/clientloop.c
index 068506210..880abfda2 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.c,v 1.328 2019/11/13 04:47:52 deraadt Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.329 2019/11/25 00:51:37 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
@@ -2003,7 +2003,8 @@ client_global_hostkeys_private_confirm(struct ssh *ssh, int type,
2003 sshkey_type_plain(ctx->keys[i]->type) == KEY_RSA; 2003 sshkey_type_plain(ctx->keys[i]->type) == KEY_RSA;
2004 if ((r = sshkey_verify(ctx->keys[i], sig, siglen, 2004 if ((r = sshkey_verify(ctx->keys[i], sig, siglen,
2005 sshbuf_ptr(signdata), sshbuf_len(signdata), 2005 sshbuf_ptr(signdata), sshbuf_len(signdata),
2006 use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0)) != 0) { 2006 use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0,
2007 NULL)) != 0) {
2007 error("%s: server gave bad signature for %s key %zu", 2008 error("%s: server gave bad signature for %s key %zu",
2008 __func__, sshkey_type(ctx->keys[i]), i); 2009 __func__, sshkey_type(ctx->keys[i]), i);
2009 goto out; 2010 goto out;
diff --git a/kexgen.c b/kexgen.c
index bb996b504..69348b964 100644
--- a/kexgen.c
+++ b/kexgen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexgen.c,v 1.3 2019/09/06 05:23:55 djm Exp $ */ 1/* $OpenBSD: kexgen.c,v 1.4 2019/11/25 00:51:37 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2019 Markus Friedl. All rights reserved. 3 * Copyright (c) 2019 Markus Friedl. All rights reserved.
4 * 4 *
@@ -212,7 +212,7 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh)
212 goto out; 212 goto out;
213 213
214 if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen, 214 if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen,
215 kex->hostkey_alg, ssh->compat)) != 0) 215 kex->hostkey_alg, ssh->compat, NULL)) != 0)
216 goto out; 216 goto out;
217 217
218 if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) 218 if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0)
diff --git a/kexgexc.c b/kexgexc.c
index 1c65b8a18..323a659b7 100644
--- a/kexgexc.c
+++ b/kexgexc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexgexc.c,v 1.34 2019/01/23 00:30:41 djm Exp $ */ 1/* $OpenBSD: kexgexc.c,v 1.35 2019/11/25 00:51:37 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Niels Provos. All rights reserved. 3 * Copyright (c) 2000 Niels Provos. All rights reserved.
4 * Copyright (c) 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -199,7 +199,7 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh)
199 goto out; 199 goto out;
200 200
201 if ((r = sshkey_verify(server_host_key, signature, slen, hash, 201 if ((r = sshkey_verify(server_host_key, signature, slen, hash,
202 hashlen, kex->hostkey_alg, ssh->compat)) != 0) 202 hashlen, kex->hostkey_alg, ssh->compat, NULL)) != 0)
203 goto out; 203 goto out;
204 204
205 if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) 205 if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0)
diff --git a/krl.c b/krl.c
index 89cb433bd..aa8318cf1 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.45 2019/10/31 21:23:19 djm Exp $ */ 17/* $OpenBSD: krl.c,v 1.46 2019/11/25 00:51:37 djm Exp $ */
18 18
19#include "includes.h" 19#include "includes.h"
20 20
@@ -1079,7 +1079,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
1079 } 1079 }
1080 /* Check signature over entire KRL up to this point */ 1080 /* Check signature over entire KRL up to this point */
1081 if ((r = sshkey_verify(key, blob, blen, 1081 if ((r = sshkey_verify(key, blob, blen,
1082 sshbuf_ptr(buf), sig_off, NULL, 0)) != 0) 1082 sshbuf_ptr(buf), sig_off, NULL, 0, NULL)) != 0)
1083 goto out; 1083 goto out;
1084 /* Check if this key has already signed this KRL */ 1084 /* Check if this key has already signed this KRL */
1085 for (i = 0; i < nca_used; i++) { 1085 for (i = 0; i < nca_used; i++) {
diff --git a/monitor.c b/monitor.c
index 1186c1dd5..40ff43ee2 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor.c,v 1.201 2019/11/19 22:21:15 djm Exp $ */ 1/* $OpenBSD: monitor.c,v 1.202 2019/11/25 00:51:37 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>
@@ -1391,6 +1391,7 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m)
1391 char *sigalg; 1391 char *sigalg;
1392 size_t signaturelen, datalen, bloblen; 1392 size_t signaturelen, datalen, bloblen;
1393 int r, ret, valid_data = 0, encoded_ret; 1393 int r, ret, valid_data = 0, encoded_ret;
1394 struct sshkey_sig_details *sig_details = NULL;
1394 1395
1395 if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 || 1396 if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 ||
1396 (r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 || 1397 (r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 ||
@@ -1430,7 +1431,7 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m)
1430 fatal("%s: bad signature data blob", __func__); 1431 fatal("%s: bad signature data blob", __func__);
1431 1432
1432 ret = sshkey_verify(key, signature, signaturelen, data, datalen, 1433 ret = sshkey_verify(key, signature, signaturelen, data, datalen,
1433 sigalg, ssh->compat); 1434 sigalg, ssh->compat, &sig_details);
1434 debug3("%s: %s %p signature %s%s%s", __func__, auth_method, key, 1435 debug3("%s: %s %p signature %s%s%s", __func__, auth_method, key,
1435 (ret == 0) ? "verified" : "unverified", 1436 (ret == 0) ? "verified" : "unverified",
1436 (ret != 0) ? ": " : "", (ret != 0) ? ssh_err(ret) : ""); 1437 (ret != 0) ? ": " : "", (ret != 0) ? ssh_err(ret) : "");
@@ -1450,8 +1451,15 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m)
1450 1451
1451 /* encode ret != 0 as positive integer, since we're sending u32 */ 1452 /* encode ret != 0 as positive integer, since we're sending u32 */
1452 encoded_ret = (ret != 0); 1453 encoded_ret = (ret != 0);
1453 if ((r = sshbuf_put_u32(m, encoded_ret)) != 0) 1454 if ((r = sshbuf_put_u32(m, encoded_ret)) != 0 ||
1455 (r = sshbuf_put_u8(m, sig_details != NULL != 0)) != 0)
1454 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1456 fatal("%s: buffer error: %s", __func__, ssh_err(r));
1457 if (sig_details != NULL) {
1458 if ((r = sshbuf_put_u32(m, sig_details->sk_counter)) != 0 ||
1459 (r = sshbuf_put_u8(m, sig_details->sk_flags)) != 0)
1460 fatal("%s: buffer error: %s", __func__, ssh_err(r));
1461 }
1462 sshkey_sig_details_free(sig_details);
1455 mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m); 1463 mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m);
1456 1464
1457 return ret == 0; 1465 return ret == 0;
diff --git a/monitor_wrap.c b/monitor_wrap.c
index 5b42c0e56..06599e3b1 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor_wrap.c,v 1.115 2019/11/18 16:10:05 naddy Exp $ */ 1/* $OpenBSD: monitor_wrap.c,v 1.116 2019/11/25 00:51:37 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>
@@ -495,15 +495,19 @@ mm_key_allowed(enum mm_keytype type, const char *user, const char *host,
495 495
496int 496int
497mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, 497mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen,
498 const u_char *data, size_t datalen, const char *sigalg, u_int compat) 498 const u_char *data, size_t datalen, const char *sigalg, u_int compat,
499 struct sshkey_sig_details **sig_detailsp)
499{ 500{
500 struct sshbuf *m; 501 struct sshbuf *m;
501 u_int encoded_ret = 0; 502 u_int encoded_ret = 0;
502 int r; 503 int r;
504 u_char sig_details_present, flags;
505 u_int counter;
503 506
504 debug3("%s entering", __func__); 507 debug3("%s entering", __func__);
505 508
506 509 if (sig_detailsp != NULL)
510 *sig_detailsp = NULL;
507 if ((m = sshbuf_new()) == NULL) 511 if ((m = sshbuf_new()) == NULL)
508 fatal("%s: sshbuf_new failed", __func__); 512 fatal("%s: sshbuf_new failed", __func__);
509 if ((r = sshkey_puts(key, m)) != 0 || 513 if ((r = sshkey_puts(key, m)) != 0 ||
@@ -518,8 +522,19 @@ mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen,
518 mm_request_receive_expect(pmonitor->m_recvfd, 522 mm_request_receive_expect(pmonitor->m_recvfd,
519 MONITOR_ANS_KEYVERIFY, m); 523 MONITOR_ANS_KEYVERIFY, m);
520 524
521 if ((r = sshbuf_get_u32(m, &encoded_ret)) != 0) 525 if ((r = sshbuf_get_u32(m, &encoded_ret)) != 0 ||
526 (r = sshbuf_get_u8(m, &sig_details_present)) != 0)
522 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 527 fatal("%s: buffer error: %s", __func__, ssh_err(r));
528 if (sig_details_present && encoded_ret == 0) {
529 if ((r = sshbuf_get_u32(m, &counter)) != 0 ||
530 (r = sshbuf_get_u8(m, &flags)) != 0)
531 fatal("%s: buffer error: %s", __func__, ssh_err(r));
532 if (sig_detailsp != NULL) {
533 *sig_detailsp = xcalloc(1, sizeof(**sig_detailsp));
534 (*sig_detailsp)->sk_counter = counter;
535 (*sig_detailsp)->sk_flags = flags;
536 }
537 }
523 538
524 sshbuf_free(m); 539 sshbuf_free(m);
525 540
diff --git a/monitor_wrap.h b/monitor_wrap.h
index 76330fc60..23ab096aa 100644
--- a/monitor_wrap.h
+++ b/monitor_wrap.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor_wrap.h,v 1.43 2019/10/31 21:23:19 djm Exp $ */ 1/* $OpenBSD: monitor_wrap.h,v 1.44 2019/11/25 00:51:37 djm Exp $ */
2 2
3/* 3/*
4 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 4 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -38,6 +38,7 @@ struct monitor;
38struct Authctxt; 38struct Authctxt;
39struct sshkey; 39struct sshkey;
40struct sshauthopt; 40struct sshauthopt;
41struct sshkey_sig_details;
41 42
42void mm_log_handler(LogLevel, const char *, void *); 43void mm_log_handler(LogLevel, const char *, void *);
43int mm_is_monitor(void); 44int mm_is_monitor(void);
@@ -57,7 +58,7 @@ int mm_user_key_allowed(struct ssh *, struct passwd *, struct sshkey *, int,
57int mm_hostbased_key_allowed(struct ssh *, struct passwd *, const char *, 58int mm_hostbased_key_allowed(struct ssh *, struct passwd *, const char *,
58 const char *, struct sshkey *); 59 const char *, struct sshkey *);
59int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, 60int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t,
60 const u_char *, size_t, const char *, u_int); 61 const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **);
61 62
62#ifdef GSSAPI 63#ifdef GSSAPI
63OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); 64OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
diff --git a/ssh-add.c b/ssh-add.c
index 6b1962bc2..1d85e9d60 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-add.c,v 1.146 2019/11/18 16:10:05 naddy Exp $ */ 1/* $OpenBSD: ssh-add.c,v 1.147 2019/11/25 00:51:37 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
@@ -451,7 +451,7 @@ test_key(int agent_fd, const char *filename)
451 goto done; 451 goto done;
452 } 452 }
453 if ((r = sshkey_verify(key, sig, slen, data, sizeof(data), 453 if ((r = sshkey_verify(key, sig, slen, data, sizeof(data),
454 NULL, 0)) != 0) { 454 NULL, 0, NULL)) != 0) {
455 error("Signature verification failed for %s: %s", 455 error("Signature verification failed for %s: %s",
456 filename, ssh_err(r)); 456 filename, ssh_err(r));
457 goto done; 457 goto done;
diff --git a/ssh-ecdsa-sk.c b/ssh-ecdsa-sk.c
index f33fac714..b2f31ae2d 100644
--- a/ssh-ecdsa-sk.c
+++ b/ssh-ecdsa-sk.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-ecdsa-sk.c,v 1.3 2019/11/25 00:38:17 djm Exp $ */ 1/* $OpenBSD: ssh-ecdsa-sk.c,v 1.4 2019/11/25 00:51:37 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) 2010 Damien Miller. All rights reserved. 4 * Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -53,7 +53,8 @@
53int 53int
54ssh_ecdsa_sk_verify(const struct sshkey *key, 54ssh_ecdsa_sk_verify(const struct sshkey *key,
55 const u_char *signature, size_t signaturelen, 55 const u_char *signature, size_t signaturelen,
56 const u_char *data, size_t datalen, u_int compat) 56 const u_char *data, size_t datalen, u_int compat,
57 struct sshkey_sig_details **detailsp)
57{ 58{
58 ECDSA_SIG *sig = NULL; 59 ECDSA_SIG *sig = NULL;
59 BIGNUM *sig_r = NULL, *sig_s = NULL; 60 BIGNUM *sig_r = NULL, *sig_s = NULL;
@@ -63,10 +64,13 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
63 int ret = SSH_ERR_INTERNAL_ERROR; 64 int ret = SSH_ERR_INTERNAL_ERROR;
64 struct sshbuf *b = NULL, *sigbuf = NULL, *original_signed = NULL; 65 struct sshbuf *b = NULL, *sigbuf = NULL, *original_signed = NULL;
65 char *ktype = NULL; 66 char *ktype = NULL;
67 struct sshkey_sig_details *details = NULL;
66#ifdef DEBUG_SK 68#ifdef DEBUG_SK
67 char *tmp = NULL; 69 char *tmp = NULL;
68#endif 70#endif
69 71
72 if (detailsp != NULL)
73 *detailsp = NULL;
70 if (key == NULL || key->ecdsa == NULL || 74 if (key == NULL || key->ecdsa == NULL ||
71 sshkey_type_plain(key->type) != KEY_ECDSA_SK || 75 sshkey_type_plain(key->type) != KEY_ECDSA_SK ||
72 signature == NULL || signaturelen == 0) 76 signature == NULL || signaturelen == 0)
@@ -149,6 +153,12 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
149 if ((ret = ssh_digest_buffer(SSH_DIGEST_SHA256, original_signed, 153 if ((ret = ssh_digest_buffer(SSH_DIGEST_SHA256, original_signed,
150 sighash, sizeof(sighash))) != 0) 154 sighash, sizeof(sighash))) != 0)
151 goto out; 155 goto out;
156 if ((details = calloc(1, sizeof(*details))) == NULL) {
157 ret = SSH_ERR_ALLOC_FAIL;
158 goto out;
159 }
160 details->sk_counter = sig_counter;
161 details->sk_flags = sig_flags;
152#ifdef DEBUG_SK 162#ifdef DEBUG_SK
153 fprintf(stderr, "%s: signed buf:\n", __func__); 163 fprintf(stderr, "%s: signed buf:\n", __func__);
154 sshbuf_dump(original_signed, stderr); 164 sshbuf_dump(original_signed, stderr);
@@ -168,13 +178,18 @@ ssh_ecdsa_sk_verify(const struct sshkey *key,
168 ret = SSH_ERR_LIBCRYPTO_ERROR; 178 ret = SSH_ERR_LIBCRYPTO_ERROR;
169 goto out; 179 goto out;
170 } 180 }
171 181 /* success */
182 if (detailsp != NULL) {
183 *detailsp = details;
184 details = NULL;
185 }
172 out: 186 out:
173 explicit_bzero(&sig_flags, sizeof(sig_flags)); 187 explicit_bzero(&sig_flags, sizeof(sig_flags));
174 explicit_bzero(&sig_counter, sizeof(sig_counter)); 188 explicit_bzero(&sig_counter, sizeof(sig_counter));
175 explicit_bzero(msghash, sizeof(msghash)); 189 explicit_bzero(msghash, sizeof(msghash));
176 explicit_bzero(sighash, sizeof(msghash)); 190 explicit_bzero(sighash, sizeof(msghash));
177 explicit_bzero(apphash, sizeof(apphash)); 191 explicit_bzero(apphash, sizeof(apphash));
192 sshkey_sig_details_free(details);
178 sshbuf_free(original_signed); 193 sshbuf_free(original_signed);
179 sshbuf_free(sigbuf); 194 sshbuf_free(sigbuf);
180 sshbuf_free(b); 195 sshbuf_free(b);
diff --git a/ssh-ed25519-sk.c b/ssh-ed25519-sk.c
index 622cb45c2..d11fde6fd 100644
--- a/ssh-ed25519-sk.c
+++ b/ssh-ed25519-sk.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-ed25519-sk.c,v 1.2 2019/11/12 19:34:40 markus Exp $ */ 1/* $OpenBSD: ssh-ed25519-sk.c,v 1.3 2019/11/25 00:51:37 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2019 Markus Friedl. All rights reserved. 3 * Copyright (c) 2019 Markus Friedl. All rights reserved.
4 * 4 *
@@ -33,7 +33,8 @@
33int 33int
34ssh_ed25519_sk_verify(const struct sshkey *key, 34ssh_ed25519_sk_verify(const struct sshkey *key,
35 const u_char *signature, size_t signaturelen, 35 const u_char *signature, size_t signaturelen,
36 const u_char *data, size_t datalen, u_int compat) 36 const u_char *data, size_t datalen, u_int compat,
37 struct sshkey_sig_details **detailsp)
37{ 38{
38 struct sshbuf *b = NULL; 39 struct sshbuf *b = NULL;
39 struct sshbuf *encoded = NULL; 40 struct sshbuf *encoded = NULL;
@@ -49,6 +50,10 @@ ssh_ed25519_sk_verify(const struct sshkey *key,
49 unsigned long long smlen = 0, mlen = 0; 50 unsigned long long smlen = 0, mlen = 0;
50 int r = SSH_ERR_INTERNAL_ERROR; 51 int r = SSH_ERR_INTERNAL_ERROR;
51 int ret; 52 int ret;
53 struct sshkey_sig_details *details = NULL;
54
55 if (detailsp != NULL)
56 *detailsp = NULL;
52 57
53 if (key == NULL || 58 if (key == NULL ||
54 sshkey_type_plain(key->type) != KEY_ED25519_SK || 59 sshkey_type_plain(key->type) != KEY_ED25519_SK ||
@@ -84,6 +89,12 @@ ssh_ed25519_sk_verify(const struct sshkey *key,
84 r = SSH_ERR_INVALID_ARGUMENT; 89 r = SSH_ERR_INVALID_ARGUMENT;
85 goto out; 90 goto out;
86 } 91 }
92 if ((details = calloc(1, sizeof(*details))) == NULL) {
93 r = SSH_ERR_ALLOC_FAIL;
94 goto out;
95 }
96 details->sk_counter = sig_counter;
97 details->sk_flags = sig_flags;
87 if ((encoded = sshbuf_new()) == NULL) { 98 if ((encoded = sshbuf_new()) == NULL) {
88 r = SSH_ERR_ALLOC_FAIL; 99 r = SSH_ERR_ALLOC_FAIL;
89 goto out; 100 goto out;
@@ -115,11 +126,16 @@ ssh_ed25519_sk_verify(const struct sshkey *key,
115 /* XXX compare 'm' and 'sm + len' ? */ 126 /* XXX compare 'm' and 'sm + len' ? */
116 /* success */ 127 /* success */
117 r = 0; 128 r = 0;
129 if (detailsp != NULL) {
130 *detailsp = details;
131 details = NULL;
132 }
118 out: 133 out:
119 if (m != NULL) { 134 if (m != NULL) {
120 explicit_bzero(m, smlen); /* NB mlen may be invalid if r != 0 */ 135 explicit_bzero(m, smlen); /* NB mlen may be invalid if r != 0 */
121 free(m); 136 free(m);
122 } 137 }
138 sshkey_sig_details_free(details);
123 sshbuf_free(b); 139 sshbuf_free(b);
124 sshbuf_free(encoded); 140 sshbuf_free(encoded);
125 free(ktype); 141 free(ktype);
diff --git a/ssh-keygen.c b/ssh-keygen.c
index e869989d7..08dd7cb8a 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.369 2019/11/18 23:16:49 naddy Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.370 2019/11/25 00:51:37 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
@@ -584,7 +584,7 @@ do_convert_private_ssh2(struct sshbuf *b)
584 if (sshkey_sign(key, &sig, &slen, data, sizeof(data), 584 if (sshkey_sign(key, &sig, &slen, data, sizeof(data),
585 NULL, NULL, 0) != 0 || 585 NULL, NULL, 0) != 0 ||
586 sshkey_verify(key, sig, slen, data, sizeof(data), 586 sshkey_verify(key, sig, slen, data, sizeof(data),
587 NULL, 0) != 0) { 587 NULL, 0, NULL) != 0) {
588 sshkey_free(key); 588 sshkey_free(key);
589 free(sig); 589 free(sig);
590 return NULL; 590 return NULL;
@@ -2657,7 +2657,9 @@ verify(const char *signature, const char *sig_namespace, const char *principal,
2657 struct sshbuf *sigbuf = NULL, *abuf = NULL; 2657 struct sshbuf *sigbuf = NULL, *abuf = NULL;
2658 struct sshkey *sign_key = NULL; 2658 struct sshkey *sign_key = NULL;
2659 char *fp = NULL; 2659 char *fp = NULL;
2660 struct sshkey_sig_details *sig_details = NULL;
2660 2661
2662 memset(&sig_details, 0, sizeof(sig_details));
2661 if ((abuf = sshbuf_new()) == NULL) 2663 if ((abuf = sshbuf_new()) == NULL)
2662 fatal("%s: sshbuf_new() failed", __func__); 2664 fatal("%s: sshbuf_new() failed", __func__);
2663 2665
@@ -2675,13 +2677,17 @@ verify(const char *signature, const char *sig_namespace, const char *principal,
2675 return r; 2677 return r;
2676 } 2678 }
2677 if ((r = sshsig_verify_fd(sigbuf, STDIN_FILENO, sig_namespace, 2679 if ((r = sshsig_verify_fd(sigbuf, STDIN_FILENO, sig_namespace,
2678 &sign_key)) != 0) 2680 &sign_key, &sig_details)) != 0)
2679 goto done; /* sshsig_verify() prints error */ 2681 goto done; /* sshsig_verify() prints error */
2680 2682
2681 if ((fp = sshkey_fingerprint(sign_key, fingerprint_hash, 2683 if ((fp = sshkey_fingerprint(sign_key, fingerprint_hash,
2682 SSH_FP_DEFAULT)) == NULL) 2684 SSH_FP_DEFAULT)) == NULL)
2683 fatal("%s: sshkey_fingerprint failed", __func__); 2685 fatal("%s: sshkey_fingerprint failed", __func__);
2684 debug("Valid (unverified) signature from key %s", fp); 2686 debug("Valid (unverified) signature from key %s", fp);
2687 if (sig_details != NULL) {
2688 debug2("%s: signature details: counter = %u, flags = 0x%02x",
2689 __func__, sig_details->sk_counter, sig_details->sk_flags);
2690 }
2685 free(fp); 2691 free(fp);
2686 fp = NULL; 2692 fp = NULL;
2687 2693
@@ -2726,6 +2732,7 @@ done:
2726 sshbuf_free(sigbuf); 2732 sshbuf_free(sigbuf);
2727 sshbuf_free(abuf); 2733 sshbuf_free(abuf);
2728 sshkey_free(sign_key); 2734 sshkey_free(sign_key);
2735 sshkey_sig_details_free(sig_details);
2729 free(fp); 2736 free(fp);
2730 return ret; 2737 return ret;
2731} 2738}
diff --git a/sshkey.c b/sshkey.c
index 48dd8bea9..920c0dc3c 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshkey.c,v 1.95 2019/11/18 06:58:00 djm Exp $ */ 1/* $OpenBSD: sshkey.c,v 1.96 2019/11/25 00:51:37 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.
@@ -2301,7 +2301,7 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
2301 goto out; 2301 goto out;
2302 } 2302 }
2303 if ((ret = sshkey_verify(key->cert->signature_key, sig, slen, 2303 if ((ret = sshkey_verify(key->cert->signature_key, sig, slen,
2304 sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0)) != 0) 2304 sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0, NULL)) != 0)
2305 goto out; 2305 goto out;
2306 if ((ret = sshkey_get_sigtype(sig, slen, 2306 if ((ret = sshkey_get_sigtype(sig, slen,
2307 &key->cert->signature_type)) != 0) 2307 &key->cert->signature_type)) != 0)
@@ -2796,8 +2796,11 @@ sshkey_sign(struct sshkey *key,
2796int 2796int
2797sshkey_verify(const struct sshkey *key, 2797sshkey_verify(const struct sshkey *key,
2798 const u_char *sig, size_t siglen, 2798 const u_char *sig, size_t siglen,
2799 const u_char *data, size_t dlen, const char *alg, u_int compat) 2799 const u_char *data, size_t dlen, const char *alg, u_int compat,
2800 struct sshkey_sig_details **detailsp)
2800{ 2801{
2802 if (detailsp != NULL)
2803 *detailsp = NULL;
2801 if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE) 2804 if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE)
2802 return SSH_ERR_INVALID_ARGUMENT; 2805 return SSH_ERR_INVALID_ARGUMENT;
2803 switch (key->type) { 2806 switch (key->type) {
@@ -2813,7 +2816,7 @@ sshkey_verify(const struct sshkey *key,
2813 case KEY_ECDSA_SK_CERT: 2816 case KEY_ECDSA_SK_CERT:
2814 case KEY_ECDSA_SK: 2817 case KEY_ECDSA_SK:
2815 return ssh_ecdsa_sk_verify(key, sig, siglen, data, dlen, 2818 return ssh_ecdsa_sk_verify(key, sig, siglen, data, dlen,
2816 compat); 2819 compat, detailsp);
2817# endif /* ENABLE_SK */ 2820# endif /* ENABLE_SK */
2818# endif /* OPENSSL_HAS_ECC */ 2821# endif /* OPENSSL_HAS_ECC */
2819 case KEY_RSA_CERT: 2822 case KEY_RSA_CERT:
@@ -2826,7 +2829,7 @@ sshkey_verify(const struct sshkey *key,
2826 case KEY_ED25519_SK: 2829 case KEY_ED25519_SK:
2827 case KEY_ED25519_SK_CERT: 2830 case KEY_ED25519_SK_CERT:
2828 return ssh_ed25519_sk_verify(key, sig, siglen, data, dlen, 2831 return ssh_ed25519_sk_verify(key, sig, siglen, data, dlen,
2829 compat); 2832 compat, detailsp);
2830#ifdef WITH_XMSS 2833#ifdef WITH_XMSS
2831 case KEY_XMSS: 2834 case KEY_XMSS:
2832 case KEY_XMSS_CERT: 2835 case KEY_XMSS_CERT:
@@ -4661,6 +4664,12 @@ sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase,
4661 passphrase, keyp, commentp); 4664 passphrase, keyp, commentp);
4662} 4665}
4663 4666
4667void
4668sshkey_sig_details_free(struct sshkey_sig_details *details)
4669{
4670 freezero(details, sizeof(*details));
4671}
4672
4664#ifdef WITH_XMSS 4673#ifdef WITH_XMSS
4665/* 4674/*
4666 * serialize the key with the current state and forward the state 4675 * serialize the key with the current state and forward the state
diff --git a/sshkey.h b/sshkey.h
index a34a4cb48..56c0a9cdf 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshkey.h,v 1.39 2019/11/13 07:53:10 markus Exp $ */ 1/* $OpenBSD: sshkey.h,v 1.40 2019/11/25 00:51:37 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.
@@ -156,6 +156,12 @@ struct sshkey {
156#define ED25519_SK_SZ crypto_sign_ed25519_SECRETKEYBYTES 156#define ED25519_SK_SZ crypto_sign_ed25519_SECRETKEYBYTES
157#define ED25519_PK_SZ crypto_sign_ed25519_PUBLICKEYBYTES 157#define ED25519_PK_SZ crypto_sign_ed25519_PUBLICKEYBYTES
158 158
159/* Additional fields contained in signature */
160struct sshkey_sig_details {
161 uint32_t sk_counter; /* U2F signature counter */
162 uint8_t sk_flags; /* U2F signature flags; see ssh-sk.h */
163};
164
159struct sshkey *sshkey_new(int); 165struct sshkey *sshkey_new(int);
160void sshkey_free(struct sshkey *); 166void sshkey_free(struct sshkey *);
161int sshkey_equal_public(const struct sshkey *, 167int sshkey_equal_public(const struct sshkey *,
@@ -230,7 +236,7 @@ int sshkey_putb_plain(const struct sshkey *, struct sshbuf *);
230int sshkey_sign(struct sshkey *, u_char **, size_t *, 236int sshkey_sign(struct sshkey *, u_char **, size_t *,
231 const u_char *, size_t, const char *, const char *, u_int); 237 const u_char *, size_t, const char *, const char *, u_int);
232int sshkey_verify(const struct sshkey *, const u_char *, size_t, 238int sshkey_verify(const struct sshkey *, const u_char *, size_t,
233 const u_char *, size_t, const char *, u_int); 239 const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **);
234int sshkey_check_sigtype(const u_char *, size_t, const char *); 240int sshkey_check_sigtype(const u_char *, size_t, const char *);
235const char *sshkey_sigalg_by_name(const char *); 241const char *sshkey_sigalg_by_name(const char *);
236int sshkey_get_sigtype(const u_char *, size_t, char **); 242int sshkey_get_sigtype(const u_char *, size_t, char **);
@@ -270,6 +276,8 @@ int sshkey_forward_state(const struct sshkey *, u_int32_t, sshkey_printfn *);
270int sshkey_private_serialize_maxsign(struct sshkey *key, struct sshbuf *buf, 276int sshkey_private_serialize_maxsign(struct sshkey *key, struct sshbuf *buf,
271 u_int32_t maxsign, sshkey_printfn *pr); 277 u_int32_t maxsign, sshkey_printfn *pr);
272 278
279void sshkey_sig_details_free(struct sshkey_sig_details *);
280
273#ifdef SSHKEY_INTERNAL 281#ifdef SSHKEY_INTERNAL
274int ssh_rsa_sign(const struct sshkey *key, 282int ssh_rsa_sign(const struct sshkey *key,
275 u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, 283 u_char **sigp, size_t *lenp, const u_char *data, size_t datalen,
@@ -289,7 +297,8 @@ int ssh_ecdsa_verify(const struct sshkey *key,
289 const u_char *data, size_t datalen, u_int compat); 297 const u_char *data, size_t datalen, u_int compat);
290int ssh_ecdsa_sk_verify(const struct sshkey *key, 298int ssh_ecdsa_sk_verify(const struct sshkey *key,
291 const u_char *signature, size_t signaturelen, 299 const u_char *signature, size_t signaturelen,
292 const u_char *data, size_t datalen, u_int compat); 300 const u_char *data, size_t datalen, u_int compat,
301 struct sshkey_sig_details **detailsp);
293int ssh_ed25519_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, 302int ssh_ed25519_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
294 const u_char *data, size_t datalen, u_int compat); 303 const u_char *data, size_t datalen, u_int compat);
295int ssh_ed25519_verify(const struct sshkey *key, 304int ssh_ed25519_verify(const struct sshkey *key,
@@ -297,7 +306,8 @@ int ssh_ed25519_verify(const struct sshkey *key,
297 const u_char *data, size_t datalen, u_int compat); 306 const u_char *data, size_t datalen, u_int compat);
298int ssh_ed25519_sk_verify(const struct sshkey *key, 307int ssh_ed25519_sk_verify(const struct sshkey *key,
299 const u_char *signature, size_t signaturelen, 308 const u_char *signature, size_t signaturelen,
300 const u_char *data, size_t datalen, u_int compat); 309 const u_char *data, size_t datalen, u_int compat,
310 struct sshkey_sig_details **detailsp);
301int ssh_xmss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, 311int ssh_xmss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
302 const u_char *data, size_t datalen, u_int compat); 312 const u_char *data, size_t datalen, u_int compat);
303int ssh_xmss_verify(const struct sshkey *key, 313int ssh_xmss_verify(const struct sshkey *key,
diff --git a/sshsig.c b/sshsig.c
index 8c7aba1b9..abba3f67b 100644
--- a/sshsig.c
+++ b/sshsig.c
@@ -286,7 +286,7 @@ sshsig_peek_hashalg(struct sshbuf *signature, char **hashalgp)
286static int 286static int
287sshsig_wrap_verify(struct sshbuf *signature, const char *hashalg, 287sshsig_wrap_verify(struct sshbuf *signature, const char *hashalg,
288 const struct sshbuf *h_message, const char *expect_namespace, 288 const struct sshbuf *h_message, const char *expect_namespace,
289 struct sshkey **sign_keyp) 289 struct sshkey **sign_keyp, struct sshkey_sig_details **sig_details)
290{ 290{
291 int r = SSH_ERR_INTERNAL_ERROR; 291 int r = SSH_ERR_INTERNAL_ERROR;
292 struct sshbuf *buf = NULL, *toverify = NULL; 292 struct sshbuf *buf = NULL, *toverify = NULL;
@@ -296,6 +296,8 @@ sshsig_wrap_verify(struct sshbuf *signature, const char *hashalg,
296 size_t siglen; 296 size_t siglen;
297 297
298 debug("%s: verify message length %zu", __func__, sshbuf_len(h_message)); 298 debug("%s: verify message length %zu", __func__, sshbuf_len(h_message));
299 if (sig_details != NULL)
300 *sig_details = NULL;
299 if (sign_keyp != NULL) 301 if (sign_keyp != NULL)
300 *sign_keyp = NULL; 302 *sign_keyp = NULL;
301 303
@@ -361,7 +363,7 @@ sshsig_wrap_verify(struct sshbuf *signature, const char *hashalg,
361 } 363 }
362 } 364 }
363 if ((r = sshkey_verify(key, sig, siglen, sshbuf_ptr(toverify), 365 if ((r = sshkey_verify(key, sig, siglen, sshbuf_ptr(toverify),
364 sshbuf_len(toverify), NULL, 0)) != 0) { 366 sshbuf_len(toverify), NULL, 0, sig_details)) != 0) {
365 error("Signature verification failed: %s", ssh_err(r)); 367 error("Signature verification failed: %s", ssh_err(r));
366 goto done; 368 goto done;
367 } 369 }
@@ -453,15 +455,17 @@ sshsig_signb(struct sshkey *key, const char *hashalg, const char *sk_provider,
453 455
454int 456int
455sshsig_verifyb(struct sshbuf *signature, const struct sshbuf *message, 457sshsig_verifyb(struct sshbuf *signature, const struct sshbuf *message,
456 const char *expect_namespace, struct sshkey **sign_keyp) 458 const char *expect_namespace, struct sshkey **sign_keyp,
459 struct sshkey_sig_details **sig_details)
457{ 460{
458 struct sshbuf *b = NULL; 461 struct sshbuf *b = NULL;
459 int r = SSH_ERR_INTERNAL_ERROR; 462 int r = SSH_ERR_INTERNAL_ERROR;
460 char *hashalg = NULL; 463 char *hashalg = NULL;
461 464
465 if (sig_details != NULL)
466 *sig_details = NULL;
462 if (sign_keyp != NULL) 467 if (sign_keyp != NULL)
463 *sign_keyp = NULL; 468 *sign_keyp = NULL;
464
465 if ((r = sshsig_peek_hashalg(signature, &hashalg)) != 0) 469 if ((r = sshsig_peek_hashalg(signature, &hashalg)) != 0)
466 return r; 470 return r;
467 debug("%s: signature made with hash \"%s\"", __func__, hashalg); 471 debug("%s: signature made with hash \"%s\"", __func__, hashalg);
@@ -470,7 +474,7 @@ sshsig_verifyb(struct sshbuf *signature, const struct sshbuf *message,
470 goto out; 474 goto out;
471 } 475 }
472 if ((r = sshsig_wrap_verify(signature, hashalg, b, expect_namespace, 476 if ((r = sshsig_wrap_verify(signature, hashalg, b, expect_namespace,
473 sign_keyp)) != 0) 477 sign_keyp, sig_details)) != 0)
474 goto out; 478 goto out;
475 /* success */ 479 /* success */
476 r = 0; 480 r = 0;
@@ -579,15 +583,17 @@ sshsig_sign_fd(struct sshkey *key, const char *hashalg, const char *sk_provider,
579 583
580int 584int
581sshsig_verify_fd(struct sshbuf *signature, int fd, 585sshsig_verify_fd(struct sshbuf *signature, int fd,
582 const char *expect_namespace, struct sshkey **sign_keyp) 586 const char *expect_namespace, struct sshkey **sign_keyp,
587 struct sshkey_sig_details **sig_details)
583{ 588{
584 struct sshbuf *b = NULL; 589 struct sshbuf *b = NULL;
585 int r = SSH_ERR_INTERNAL_ERROR; 590 int r = SSH_ERR_INTERNAL_ERROR;
586 char *hashalg = NULL; 591 char *hashalg = NULL;
587 592
593 if (sig_details != NULL)
594 *sig_details = NULL;
588 if (sign_keyp != NULL) 595 if (sign_keyp != NULL)
589 *sign_keyp = NULL; 596 *sign_keyp = NULL;
590
591 if ((r = sshsig_peek_hashalg(signature, &hashalg)) != 0) 597 if ((r = sshsig_peek_hashalg(signature, &hashalg)) != 0)
592 return r; 598 return r;
593 debug("%s: signature made with hash \"%s\"", __func__, hashalg); 599 debug("%s: signature made with hash \"%s\"", __func__, hashalg);
@@ -596,7 +602,7 @@ sshsig_verify_fd(struct sshbuf *signature, int fd,
596 goto out; 602 goto out;
597 } 603 }
598 if ((r = sshsig_wrap_verify(signature, hashalg, b, expect_namespace, 604 if ((r = sshsig_wrap_verify(signature, hashalg, b, expect_namespace,
599 sign_keyp)) != 0) 605 sign_keyp, sig_details)) != 0)
600 goto out; 606 goto out;
601 /* success */ 607 /* success */
602 r = 0; 608 r = 0;
diff --git a/sshsig.h b/sshsig.h
index 487db116c..386c8b5d7 100644
--- a/sshsig.h
+++ b/sshsig.h
@@ -20,6 +20,7 @@
20struct sshbuf; 20struct sshbuf;
21struct sshkey; 21struct sshkey;
22struct sshsigopt; 22struct sshsigopt;
23struct sshkey_sig_details;
23 24
24typedef int sshsig_signer(struct sshkey *, u_char **, size_t *, 25typedef int sshsig_signer(struct sshkey *, u_char **, size_t *,
25 const u_char *, size_t, const char *, const char *, u_int, void *); 26 const u_char *, size_t, const char *, const char *, u_int, void *);
@@ -43,7 +44,7 @@ int sshsig_signb(struct sshkey *key, const char *hashalg,
43 */ 44 */
44int sshsig_verifyb(struct sshbuf *signature, 45int sshsig_verifyb(struct sshbuf *signature,
45 const struct sshbuf *message, const char *sig_namespace, 46 const struct sshbuf *message, const char *sig_namespace,
46 struct sshkey **sign_keyp); 47 struct sshkey **sign_keyp, struct sshkey_sig_details **sig_details);
47 48
48/* File/FD-oriented API */ 49/* File/FD-oriented API */
49 50
@@ -62,7 +63,8 @@ int sshsig_sign_fd(struct sshkey *key, const char *hashalg,
62 * Returns 0 on success or a negative SSH_ERR_* error code on failure. 63 * Returns 0 on success or a negative SSH_ERR_* error code on failure.
63 */ 64 */
64int sshsig_verify_fd(struct sshbuf *signature, int fd, 65int sshsig_verify_fd(struct sshbuf *signature, int fd,
65 const char *sig_namespace, struct sshkey **sign_keyp); 66 const char *sig_namespace, struct sshkey **sign_keyp,
67 struct sshkey_sig_details **sig_details);
66 68
67/* Utility functions */ 69/* Utility functions */
68 70