1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-11-30 13:01:23 +03:00

pki: Fail to sign when using wrong hash algorithm

Do not allow using SSH_DIGEST_AUTO for any algorithm other than
ed25519.

Do not allow using incompatible hash algorithms when signing or
verifying signatures.

Added negative tests for all combinations of signature and hash
algorithms.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
Anderson Toshiyuki Sasaki
2019-05-09 17:38:54 +02:00
committed by Andreas Schneider
parent 550a1a7667
commit 248e5acd5c
9 changed files with 579 additions and 196 deletions

View File

@@ -2107,6 +2107,12 @@ int pki_signature_verify(ssh_session session,
return SSH_ERROR;
}
/* Check if public key and hash type are compatible */
rc = pki_key_check_hash_compatible(key, sig->hash_type);
if (rc != SSH_OK) {
return SSH_ERROR;
}
/* For ed25519 keys, verify using the input directly */
if (key->type == SSH_KEYTYPE_ED25519 ||
key->type == SSH_KEYTYPE_ED25519_CERT01)
@@ -2171,7 +2177,6 @@ ssh_signature pki_do_sign_hash(const ssh_key privkey,
case SSH_KEYTYPE_RSA:
switch (hash_type) {
case SSH_DIGEST_SHA1:
case SSH_DIGEST_AUTO:
hash_c = "sha1";
break;
case SSH_DIGEST_SHA256:
@@ -2180,8 +2185,9 @@ ssh_signature pki_do_sign_hash(const ssh_key privkey,
case SSH_DIGEST_SHA512:
hash_c = "sha512";
break;
case SSH_DIGEST_AUTO:
default:
SSH_LOG(SSH_LOG_WARN, "Incomplatible key algorithm");
SSH_LOG(SSH_LOG_WARN, "Incompatible key algorithm");
return NULL;
}
err = gcry_sexp_build(&sexp,
@@ -2261,6 +2267,7 @@ ssh_signature pki_sign_data(const ssh_key privkey,
{
unsigned char hash[SHA512_DIGEST_LEN] = {0};
uint32_t hlen = 0;
int rc;
if (privkey == NULL || !ssh_key_is_private(privkey) || input == NULL) {
SSH_LOG(SSH_LOG_TRACE, "Bad parameter provided to "
@@ -2268,6 +2275,12 @@ ssh_signature pki_sign_data(const ssh_key privkey,
return NULL;
}
/* Check if public key and hash type are compatible */
rc = pki_key_check_hash_compatible(privkey, hash_type);
if (rc != SSH_OK) {
return NULL;
}
switch (hash_type) {
case SSH_DIGEST_SHA256:
sha256(input, input_len, hash);
@@ -2281,11 +2294,11 @@ ssh_signature pki_sign_data(const ssh_key privkey,
sha512(input, input_len, hash);
hlen = SHA512_DIGEST_LEN;
break;
case SSH_DIGEST_AUTO:
case SSH_DIGEST_SHA1:
sha1(input, input_len, hash);
hlen = SHA_DIGEST_LEN;
break;
case SSH_DIGEST_AUTO:
default:
SSH_LOG(SSH_LOG_TRACE, "Unknown hash algorithm for type: %d",
hash_type);
@@ -2321,6 +2334,8 @@ int pki_verify_data_signature(ssh_signature signature,
unsigned char *hash = ghash + 1;
uint32_t hlen = 0;
int rc;
if (pubkey == NULL || ssh_key_is_private(pubkey) || input == NULL ||
signature == NULL)
{
@@ -2329,6 +2344,12 @@ int pki_verify_data_signature(ssh_signature signature,
return SSH_ERROR;
}
/* Check if public key and hash type are compatible */
rc = pki_key_check_hash_compatible(pubkey, signature->hash_type);
if (rc != SSH_OK) {
return SSH_ERROR;
}
switch (signature->hash_type) {
case SSH_DIGEST_SHA256:
sha256(input, input_len, hash);
@@ -2345,12 +2366,12 @@ int pki_verify_data_signature(ssh_signature signature,
hlen = SHA512_DIGEST_LEN;
hash_type = "sha512";
break;
case SSH_DIGEST_AUTO:
case SSH_DIGEST_SHA1:
sha1(input, input_len, hash);
hlen = SHA_DIGEST_LEN;
hash_type = "sha1";
break;
case SSH_DIGEST_AUTO:
default:
SSH_LOG(SSH_LOG_TRACE, "Unknown sig->hash_type: %d", signature->hash_type);
return SSH_ERROR;