summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2019-11-25 00:51:37 +0000
committerDamien Miller <djm@mindrot.org>2019-11-25 12:23:33 +1100
commitb7e74ea072919b31391bc0f5ff653f80b9f5e84f (patch)
treeadb2a736c1b9f6346d342600877818631f9dbb3d
parentd2b0f88178ec9e3f11b606bf1004ac2fe541a2c3 (diff)
upstream: Add new structure for signature options
This is populated during signature verification with additional fields that are present in and covered by the signature. At the moment, it is only used to record security key-specific options, especially the flags field. with and ok markus@ OpenBSD-Commit-ID: 338a1f0e04904008836130bedb9ece4faafd4e49
-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