diff options
-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 | ||