diff options
author | djm@openbsd.org <djm@openbsd.org> | 2019-11-25 00:51:37 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2019-11-25 12:23:33 +1100 |
commit | b7e74ea072919b31391bc0f5ff653f80b9f5e84f (patch) | |
tree | adb2a736c1b9f6346d342600877818631f9dbb3d | |
parent | d2b0f88178ec9e3f11b606bf1004ac2fe541a2c3 (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.c | 4 | ||||
-rw-r--r-- | auth2-pubkey.c | 11 | ||||
-rw-r--r-- | clientloop.c | 5 | ||||
-rw-r--r-- | kexgen.c | 4 | ||||
-rw-r--r-- | kexgexc.c | 4 | ||||
-rw-r--r-- | krl.c | 4 | ||||
-rw-r--r-- | monitor.c | 14 | ||||
-rw-r--r-- | monitor_wrap.c | 23 | ||||
-rw-r--r-- | monitor_wrap.h | 5 | ||||
-rw-r--r-- | ssh-add.c | 4 | ||||
-rw-r--r-- | ssh-ecdsa-sk.c | 21 | ||||
-rw-r--r-- | ssh-ed25519-sk.c | 20 | ||||
-rw-r--r-- | ssh-keygen.c | 13 | ||||
-rw-r--r-- | sshkey.c | 19 | ||||
-rw-r--r-- | sshkey.h | 18 | ||||
-rw-r--r-- | sshsig.c | 22 | ||||
-rw-r--r-- | sshsig.h | 6 |
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; |
@@ -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) |
@@ -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) |
@@ -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++) { |
@@ -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 | ||
496 | int | 496 | int |
497 | mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, | 497 | mm_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; | |||
38 | struct Authctxt; | 38 | struct Authctxt; |
39 | struct sshkey; | 39 | struct sshkey; |
40 | struct sshauthopt; | 40 | struct sshauthopt; |
41 | struct sshkey_sig_details; | ||
41 | 42 | ||
42 | void mm_log_handler(LogLevel, const char *, void *); | 43 | void mm_log_handler(LogLevel, const char *, void *); |
43 | int mm_is_monitor(void); | 44 | int mm_is_monitor(void); |
@@ -57,7 +58,7 @@ int mm_user_key_allowed(struct ssh *, struct passwd *, struct sshkey *, int, | |||
57 | int mm_hostbased_key_allowed(struct ssh *, struct passwd *, const char *, | 58 | int mm_hostbased_key_allowed(struct ssh *, struct passwd *, const char *, |
58 | const char *, struct sshkey *); | 59 | const char *, struct sshkey *); |
59 | int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, | 60 | int 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 |
63 | OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); | 64 | OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); |
@@ -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 @@ | |||
53 | int | 53 | int |
54 | ssh_ecdsa_sk_verify(const struct sshkey *key, | 54 | ssh_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 @@ | |||
33 | int | 33 | int |
34 | ssh_ed25519_sk_verify(const struct sshkey *key, | 34 | ssh_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 | } |
@@ -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, | |||
2796 | int | 2796 | int |
2797 | sshkey_verify(const struct sshkey *key, | 2797 | sshkey_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 | ||
4667 | void | ||
4668 | sshkey_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 |
@@ -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 */ | ||
160 | struct 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 | |||
159 | struct sshkey *sshkey_new(int); | 165 | struct sshkey *sshkey_new(int); |
160 | void sshkey_free(struct sshkey *); | 166 | void sshkey_free(struct sshkey *); |
161 | int sshkey_equal_public(const struct sshkey *, | 167 | int sshkey_equal_public(const struct sshkey *, |
@@ -230,7 +236,7 @@ int sshkey_putb_plain(const struct sshkey *, struct sshbuf *); | |||
230 | int sshkey_sign(struct sshkey *, u_char **, size_t *, | 236 | int 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); |
232 | int sshkey_verify(const struct sshkey *, const u_char *, size_t, | 238 | int 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 **); |
234 | int sshkey_check_sigtype(const u_char *, size_t, const char *); | 240 | int sshkey_check_sigtype(const u_char *, size_t, const char *); |
235 | const char *sshkey_sigalg_by_name(const char *); | 241 | const char *sshkey_sigalg_by_name(const char *); |
236 | int sshkey_get_sigtype(const u_char *, size_t, char **); | 242 | int 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 *); | |||
270 | int sshkey_private_serialize_maxsign(struct sshkey *key, struct sshbuf *buf, | 276 | int 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 | ||
279 | void sshkey_sig_details_free(struct sshkey_sig_details *); | ||
280 | |||
273 | #ifdef SSHKEY_INTERNAL | 281 | #ifdef SSHKEY_INTERNAL |
274 | int ssh_rsa_sign(const struct sshkey *key, | 282 | int 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); |
290 | int ssh_ecdsa_sk_verify(const struct sshkey *key, | 298 | int 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); | ||
293 | int ssh_ed25519_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, | 302 | int 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); |
295 | int ssh_ed25519_verify(const struct sshkey *key, | 304 | int 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); |
298 | int ssh_ed25519_sk_verify(const struct sshkey *key, | 307 | int 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); | ||
301 | int ssh_xmss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, | 311 | int 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); |
303 | int ssh_xmss_verify(const struct sshkey *key, | 313 | int ssh_xmss_verify(const struct sshkey *key, |
@@ -286,7 +286,7 @@ sshsig_peek_hashalg(struct sshbuf *signature, char **hashalgp) | |||
286 | static int | 286 | static int |
287 | sshsig_wrap_verify(struct sshbuf *signature, const char *hashalg, | 287 | sshsig_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 | ||
454 | int | 456 | int |
455 | sshsig_verifyb(struct sshbuf *signature, const struct sshbuf *message, | 457 | sshsig_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 | ||
580 | int | 584 | int |
581 | sshsig_verify_fd(struct sshbuf *signature, int fd, | 585 | sshsig_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; |
@@ -20,6 +20,7 @@ | |||
20 | struct sshbuf; | 20 | struct sshbuf; |
21 | struct sshkey; | 21 | struct sshkey; |
22 | struct sshsigopt; | 22 | struct sshsigopt; |
23 | struct sshkey_sig_details; | ||
23 | 24 | ||
24 | typedef int sshsig_signer(struct sshkey *, u_char **, size_t *, | 25 | typedef 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 | */ |
44 | int sshsig_verifyb(struct sshbuf *signature, | 45 | int 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 | */ |
64 | int sshsig_verify_fd(struct sshbuf *signature, int fd, | 65 | int 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 | ||