Bugzilla – Attachment 3104 Details for
Bug 2799
RSA Signatures using SHA2 provided by different ssh-agent are not properly verified
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
check signature type at verification time
bz2799-2.diff (text/plain), 11.68 KB, created by
Damien Miller
on 2017-12-08 17:56:11 AEDT
(
hide
)
Description:
check signature type at verification time
Filename:
MIME Type:
Creator:
Damien Miller
Created:
2017-12-08 17:56:11 AEDT
Size:
11.68 KB
patch
obsolete
>diff --git a/auth2-hostbased.c b/auth2-hostbased.c >index 3ea8311..cc2927e 100644 >--- a/auth2-hostbased.c >+++ b/auth2-hostbased.c >@@ -143,7 +143,7 @@ userauth_hostbased(struct ssh *ssh) > authenticated = 0; > if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && > PRIVSEP(sshkey_verify(key, sig, slen, >- sshbuf_ptr(b), sshbuf_len(b), ssh->compat)) == 0) >+ sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat)) == 0) > authenticated = 1; > > auth2_record_key(authctxt, authenticated, key); >diff --git a/auth2-pubkey.c b/auth2-pubkey.c >index 73cc2ed..e7907ed 100644 >--- a/auth2-pubkey.c >+++ b/auth2-pubkey.c >@@ -195,7 +195,7 @@ userauth_pubkey(struct ssh *ssh) > authenticated = 0; > if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) && > PRIVSEP(sshkey_verify(key, sig, slen, sshbuf_ptr(b), >- sshbuf_len(b), ssh->compat)) == 0) { >+ sshbuf_len(b), pkalg, ssh->compat)) == 0) { > authenticated = 1; > } > sshbuf_free(b); >diff --git a/clientloop.c b/clientloop.c >index be13321..609ca4b 100644 >--- a/clientloop.c >+++ b/clientloop.c >@@ -1919,7 +1919,8 @@ client_global_hostkeys_private_confirm(struct ssh *ssh, int type, > goto out; > } > if ((r = sshkey_verify(ctx->keys[i], sig, siglen, >- sshbuf_ptr(signdata), sshbuf_len(signdata), 0)) != 0) { >+ sshbuf_ptr(signdata), sshbuf_len(signdata), >+ ssh->kex->hostkey_alg, 0)) != 0) { > error("%s: server gave bad signature for %s key %zu", > __func__, sshkey_type(ctx->keys[i]), i); > goto out; >diff --git a/kexc25519c.c b/kexc25519c.c >index 5661d21..5fe8efc 100644 >--- a/kexc25519c.c >+++ b/kexc25519c.c >@@ -139,7 +139,7 @@ input_kex_c25519_reply(int type, u_int32_t seq, struct ssh *ssh) > goto out; > > if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen, >- ssh->compat)) != 0) >+ kex->hostkey_alg, ssh->compat)) != 0) > goto out; > > /* save session id */ >diff --git a/kexdhc.c b/kexdhc.c >index efc2772..e145a75 100644 >--- a/kexdhc.c >+++ b/kexdhc.c >@@ -178,7 +178,7 @@ input_kex_dh(int type, u_int32_t seq, struct ssh *ssh) > goto out; > > if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen, >- ssh->compat)) != 0) >+ kex->hostkey_alg, ssh->compat)) != 0) > goto out; > > /* save session id */ >diff --git a/kexecdhc.c b/kexecdhc.c >index 3222803..23b7232 100644 >--- a/kexecdhc.c >+++ b/kexecdhc.c >@@ -184,7 +184,7 @@ input_kex_ecdh_reply(int type, u_int32_t seq, struct ssh *ssh) > goto out; > > if ((r = sshkey_verify(server_host_key, signature, slen, hash, >- hashlen, ssh->compat)) != 0) >+ hashlen, kex->hostkey_alg, ssh->compat)) != 0) > goto out; > > /* save session id */ >diff --git a/kexgexc.c b/kexgexc.c >index 6107486..9cc91cd 100644 >--- a/kexgexc.c >+++ b/kexgexc.c >@@ -225,7 +225,7 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh) > goto out; > > if ((r = sshkey_verify(server_host_key, signature, slen, hash, >- hashlen, ssh->compat)) != 0) >+ hashlen, kex->hostkey_alg, ssh->compat)) != 0) > goto out; > > /* save session id */ >diff --git a/key.c b/key.c >index 921a9b5..19175cf 100644 >--- a/key.c >+++ b/key.c >@@ -93,21 +93,6 @@ key_sign(const Key *key, u_char **sigp, u_int *lenp, > return 0; > } > >-int >-key_verify(const Key *key, const u_char *signature, u_int signaturelen, >- const u_char *data, u_int datalen) >-{ >- int r; >- >- if ((r = sshkey_verify(key, signature, signaturelen, >- data, datalen, datafellows)) != 0) { >- fatal_on_fatal_errors(r, __func__, 0); >- error("%s: %s", __func__, ssh_err(r)); >- return r == SSH_ERR_SIGNATURE_INVALID ? 0 : -1; >- } >- return 1; >-} >- > Key * > key_demote(const Key *k) > { >diff --git a/key.h b/key.h >index a14f370..8589755 100644 >--- a/key.h >+++ b/key.h >@@ -58,7 +58,6 @@ int key_to_blob(const Key *, u_char **, u_int *); > > int key_sign(const Key *, u_char **, u_int *, const u_char *, u_int, > const char *); >-int key_verify(const Key *, const u_char *, u_int, const u_char *, u_int); > > /* authfile.c */ > Key *key_load_cert(const char *); >diff --git a/krl.c b/krl.c >index cb7f728..33be352 100644 >--- a/krl.c >+++ b/krl.c >@@ -1012,7 +1012,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp, > } > /* Check signature over entire KRL up to this point */ > if ((r = sshkey_verify(key, blob, blen, >- sshbuf_ptr(buf), sig_off, 0)) != 0) >+ sshbuf_ptr(buf), sig_off, NULL, 0)) != 0) > goto out; > /* Check if this key has already signed this KRL */ > for (i = 0; i < nca_used; i++) { >diff --git a/monitor.c b/monitor.c >index a6d5087..4995627 100644 >--- a/monitor.c >+++ b/monitor.c >@@ -1048,12 +1048,14 @@ mm_answer_keyverify(int sock, struct sshbuf *m) > { > struct sshkey *key; > u_char *signature, *data, *blob; >+ char *sigalg; > size_t signaturelen, datalen, bloblen; > int r, ret, valid_data = 0, encoded_ret; > > if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 || > (r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 || >- (r = sshbuf_get_string(m, &data, &datalen)) != 0) >+ (r = sshbuf_get_string(m, &data, &datalen)) != 0 || >+ (r = sshbuf_get_cstring(m, &sigalg, NULL)) != 0) > fatal("%s: buffer error: %s", __func__, ssh_err(r)); > > if (hostbased_cuser == NULL || hostbased_chost == NULL || >@@ -1082,7 +1084,7 @@ mm_answer_keyverify(int sock, struct sshbuf *m) > fatal("%s: bad signature data blob", __func__); > > ret = sshkey_verify(key, signature, signaturelen, data, datalen, >- active_state->compat); >+ sigalg, active_state->compat); > debug3("%s: %s %p signature %s", __func__, auth_method, key, > (ret == 0) ? "verified" : "unverified"); > auth2_record_key(authctxt, ret == 0, key); >diff --git a/monitor_wrap.c b/monitor_wrap.c >index 11fc243..c123ba7 100644 >--- a/monitor_wrap.c >+++ b/monitor_wrap.c >@@ -423,7 +423,7 @@ mm_key_allowed(enum mm_keytype type, const char *user, const char *host, > > int > mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, >- const u_char *data, size_t datalen, u_int compat) >+ const u_char *data, size_t datalen, const char *sigalg, u_int compat) > { > Buffer m; > u_char *blob; >@@ -440,6 +440,7 @@ mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, > buffer_put_string(&m, blob, len); > buffer_put_string(&m, sig, siglen); > buffer_put_string(&m, data, datalen); >+ buffer_put_cstring(&m, sigalg); > free(blob); > > mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m); >diff --git a/monitor_wrap.h b/monitor_wrap.h >index f484b37..575450f 100644 >--- a/monitor_wrap.h >+++ b/monitor_wrap.h >@@ -51,7 +51,7 @@ int mm_user_key_allowed(struct passwd *, struct sshkey *, int); > int mm_hostbased_key_allowed(struct passwd *, const char *, > const char *, struct sshkey *); > int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, >- const u_char *, size_t, u_int); >+ const u_char *, size_t, const char *, u_int); > > #ifdef GSSAPI > OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); >diff --git a/serverloop.c b/serverloop.c >index 955656e..688f0c8 100644 >--- a/serverloop.c >+++ b/serverloop.c >@@ -702,7 +702,8 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) > ssh->kex->session_id, ssh->kex->session_id_len)) != 0 || > (r = sshkey_puts(key, sigbuf)) != 0 || > (r = ssh->kex->sign(key_prv, key_pub, &sig, &slen, >- sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), NULL, 0)) != 0 || >+ sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), >+ ssh->kex->hostkey_alg, 0)) != 0 || > (r = sshbuf_put_string(resp, sig, slen)) != 0) { > error("%s: couldn't prepare signature: %s", > __func__, ssh_err(r)); >diff --git a/ssh-keygen.c b/ssh-keygen.c >index 282324f..8b2df24 100644 >--- a/ssh-keygen.c >+++ b/ssh-keygen.c >@@ -529,7 +529,7 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) > > /* try the key */ > if (sshkey_sign(key, &sig, &slen, data, sizeof(data), NULL, 0) != 0 || >- sshkey_verify(key, sig, slen, data, sizeof(data), 0) != 0) { >+ sshkey_verify(key, sig, slen, data, sizeof(data), NULL, 0) != 0) { > sshkey_free(key); > free(sig); > return NULL; >diff --git a/ssh-rsa.c b/ssh-rsa.c >index fa9d7f0..076b25e 100644 >--- a/ssh-rsa.c >+++ b/ssh-rsa.c >@@ -193,9 +193,10 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, > > int > ssh_rsa_verify(const struct sshkey *key, >- const u_char *sig, size_t siglen, const u_char *data, size_t datalen) >+ const u_char *sig, size_t siglen, const u_char *data, size_t datalen, >+ const char *alg) > { >- char *ktype = NULL; >+ char *sigtype = NULL; > int hash_alg, ret = SSH_ERR_INTERNAL_ERROR; > size_t len, diff, modlen, dlen; > struct sshbuf *b = NULL; >@@ -210,11 +211,17 @@ ssh_rsa_verify(const struct sshkey *key, > > if ((b = sshbuf_from(sig, siglen)) == NULL) > return SSH_ERR_ALLOC_FAIL; >- if (sshbuf_get_cstring(b, &ktype, NULL) != 0) { >+ if (sshbuf_get_cstring(b, &sigtype, NULL) != 0) { > ret = SSH_ERR_INVALID_FORMAT; > goto out; > } >- if ((hash_alg = rsa_hash_alg_from_ident(ktype)) == -1) { >+ /* XXX djm: need cert types that reliably yield SHA-2 signatures */ >+ if (alg != NULL && strcmp(alg, sigtype) != 0 && >+ strcmp(alg, "ssh-rsa-cert-v01@openssh.com") != 0) { >+ ret = SSH_ERR_SIGNATURE_INVALID; >+ goto out; >+ } >+ if ((hash_alg = rsa_hash_alg_from_ident(sigtype)) == -1) { > ret = SSH_ERR_KEY_TYPE_MISMATCH; > goto out; > } >@@ -258,7 +265,7 @@ ssh_rsa_verify(const struct sshkey *key, > explicit_bzero(sigblob, len); > free(sigblob); > } >- free(ktype); >+ free(sigtype); > sshbuf_free(b); > explicit_bzero(digest, sizeof(digest)); > return ret; >diff --git a/sshkey.c b/sshkey.c >index ed4b54e..e8c33ef 100644 >--- a/sshkey.c >+++ b/sshkey.c >@@ -1778,7 +1778,7 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf) > goto out; > } > if ((ret = sshkey_verify(key->cert->signature_key, sig, slen, >- sshbuf_ptr(key->cert->certblob), signed_len, 0)) != 0) >+ sshbuf_ptr(key->cert->certblob), signed_len, NULL, 0)) != 0) > goto out; > > /* Success */ >@@ -2067,13 +2067,16 @@ sshkey_sign(const struct sshkey *key, > } > } > >+#include "log.h" >+ > /* > * ssh_key_verify returns 0 for a correct signature and < 0 on error. >+ * If "alg" specified, then the signature must use that algorithm. > */ > int > sshkey_verify(const struct sshkey *key, > const u_char *sig, size_t siglen, >- const u_char *data, size_t dlen, u_int compat) >+ const u_char *data, size_t dlen, const char *alg, u_int compat) > { > if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE) > return SSH_ERR_INVALID_ARGUMENT; >@@ -2087,7 +2090,7 @@ sshkey_verify(const struct sshkey *key, > return ssh_ecdsa_verify(key, sig, siglen, data, dlen, compat); > case KEY_RSA_CERT: > case KEY_RSA: >- return ssh_rsa_verify(key, sig, siglen, data, dlen); >+ return ssh_rsa_verify(key, sig, siglen, data, dlen, alg); > #endif /* WITH_OPENSSL */ > case KEY_ED25519: > case KEY_ED25519_CERT: >diff --git a/sshkey.h b/sshkey.h >index b81cf8f..b45c683 100644 >--- a/sshkey.h >+++ b/sshkey.h >@@ -172,7 +172,7 @@ int sshkey_sigtype(const u_char *, size_t, char **); > int sshkey_sign(const struct sshkey *, u_char **, size_t *, > const u_char *, size_t, const char *, u_int); > int sshkey_verify(const struct sshkey *, const u_char *, size_t, >- const u_char *, size_t, u_int); >+ const u_char *, size_t, const char *, u_int); > > /* for debug */ > void sshkey_dump_ec_point(const EC_GROUP *, const EC_POINT *); >@@ -199,7 +199,8 @@ int ssh_rsa_sign(const struct sshkey *key, > u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, > const char *ident); > int ssh_rsa_verify(const struct sshkey *key, >- const u_char *sig, size_t siglen, const u_char *data, size_t datalen); >+ const u_char *sig, size_t siglen, const u_char *data, size_t datalen, >+ const char *alg); > int ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, > const u_char *data, size_t datalen, u_int compat); > int ssh_dss_verify(const struct sshkey *key,
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 2799
:
3090
|
3092
|
3100
|
3104
|
3135