aboutsummaryrefslogtreecommitdiff
path: root/src/pki.c
diff options
context:
space:
mode:
authorAnderson Toshiyuki Sasaki <ansasaki@redhat.com>2019-04-29 16:29:16 +0200
committerAndreas Schneider <asn@cryptomilk.org>2019-05-13 16:37:51 +0200
commit76f9808eb2fa83376981cebba63b467fa3a8c4be (patch)
tree07b85c0332fad460568f46a0b65a01d44c00190f /src/pki.c
parent58b3b2696c9080dfbd21132a1b05604ef064d880 (diff)
downloadlibssh-76f9808eb2fa83376981cebba63b467fa3a8c4be.tar.gz
libssh-76f9808eb2fa83376981cebba63b467fa3a8c4be.tar.xz
libssh-76f9808eb2fa83376981cebba63b467fa3a8c4be.zip
auth, pki: Calculate hash internally when signing/verifying
This makes pki_do_sign() and pki_signature_verify() to receive the original input instead of the pre-calculated hash. The hash is then calculated internally. The hash to be used inside the signature is decided earlier, when all the information about the signature to be generated/verified is available. Simplify ssh_pki_do_sign() and ssh_srv_pki_do_sign_sessionid(). The tests were modified to use pki_do_sign() instead of pki_do_sign_hash(). Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com> Reviewed-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Diffstat (limited to 'src/pki.c')
-rw-r--r--src/pki.c218
1 files changed, 69 insertions, 149 deletions
diff --git a/src/pki.c b/src/pki.c
index fcce8863..911b75f5 100644
--- a/src/pki.c
+++ b/src/pki.c
@@ -2064,12 +2064,18 @@ int ssh_pki_import_signature_blob(const ssh_string sig_blob,
int ssh_pki_signature_verify(ssh_session session,
ssh_signature sig,
const ssh_key key,
- unsigned char *digest,
- size_t dlen)
+ unsigned char *input,
+ size_t input_len)
{
int rc;
enum ssh_keytypes_e key_type = ssh_key_type_plain(key->type);
+ if (session == NULL || sig == NULL || key == NULL || input == NULL) {
+ SSH_LOG(SSH_LOG_TRACE, "Bad parameter provided to "
+ "ssh_pki_signature_verify()");
+ return SSH_ERROR;
+ }
+
SSH_LOG(SSH_LOG_FUNCTIONS,
"Going to verify a %s type signature",
sig->type_c);
@@ -2081,69 +2087,59 @@ int ssh_pki_signature_verify(ssh_session session,
return SSH_ERROR;
}
- if (is_ecdsa_key_type(key_type)) {
-#if HAVE_ECC
- unsigned char ehash[EVP_DIGEST_LEN] = {0};
- uint32_t elen;
+ rc = pki_signature_verify(session, sig, key, input, input_len);
- evp(key->ecdsa_nid, digest, dlen, ehash, &elen);
-
-#ifdef DEBUG_CRYPTO
- ssh_print_hexa("Hash to be verified with ecdsa",
- ehash, elen);
-#endif
+ return rc;
+}
- rc = pki_signature_verify(session,
- sig,
- key,
- ehash,
- elen);
-#endif
- } else if (key_type == SSH_KEYTYPE_ED25519) {
- rc = pki_signature_verify(session, sig, key, digest, dlen);
- } else {
- unsigned char hash[SHA512_DIGEST_LEN] = {0};
- uint32_t hlen = 0;
+ssh_signature pki_do_sign(const ssh_key privkey,
+ const unsigned char *input,
+ size_t input_len,
+ enum ssh_digest_e hash_type)
+{
+ unsigned char hash[SHA512_DIGEST_LEN] = {0};
+ uint32_t hlen = 0;
- if (sig->type != SSH_KEYTYPE_RSA && sig->hash_type != SSH_DIGEST_AUTO) {
- SSH_LOG(SSH_LOG_TRACE, "Only RSA keys support non-SHA1 hashes.");
- return SSH_ERROR;
- }
+ if (privkey == NULL || input == NULL) {
+ SSH_LOG(SSH_LOG_TRACE, "Bad parameter provided to "
+ "pki_do_sign()");
+ return NULL;
+ }
- switch (sig->hash_type) {
- case SSH_DIGEST_SHA256:
- sha256(digest, dlen, hash);
- hlen = SHA256_DIGEST_LEN;
- break;
- case SSH_DIGEST_SHA512:
- sha512(digest, dlen, hash);
- hlen = SHA512_DIGEST_LEN;
- break;
- case SSH_DIGEST_SHA1:
- case SSH_DIGEST_AUTO:
- sha1(digest, dlen, hash);
- hlen = SHA_DIGEST_LEN;
- break;
- default:
- SSH_LOG(SSH_LOG_TRACE, "Unknown sig->hash_type: %d", sig->hash_type);
- return SSH_ERROR;
- }
-#ifdef DEBUG_CRYPTO
- ssh_print_hexa(key_type == SSH_KEYTYPE_DSS
- ? "Hash to be verified with DSA"
- : "Hash to be verified with RSA",
- hash,
- hlen);
-#endif
+ if (privkey->type == SSH_KEYTYPE_ED25519 ||
+ privkey->type == SSH_KEYTYPE_ED25519_CERT01)
+ {
+ return pki_do_sign_hash(privkey, input, input_len, SSH_DIGEST_AUTO);
+ }
- rc = pki_signature_verify(session,
- sig,
- key,
- hash,
- hlen);
+ switch (hash_type) {
+ case SSH_DIGEST_SHA256:
+ sha256(input, input_len, hash);
+ hlen = SHA256_DIGEST_LEN;
+ break;
+ case SSH_DIGEST_SHA384:
+ sha384(input, input_len, hash);
+ hlen = SHA384_DIGEST_LEN;
+ break;
+ case SSH_DIGEST_SHA512:
+ 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;
+ default:
+ SSH_LOG(SSH_LOG_TRACE, "Unknown hash algorithm for type: %d",
+ hash_type);
+ goto error;
}
- return rc;
+ return pki_do_sign_hash(privkey, hash, hlen, hash_type);
+
+error:
+ return NULL;
}
/*
@@ -2151,7 +2147,8 @@ int ssh_pki_signature_verify(ssh_session session,
* the content of sigbuf */
ssh_string ssh_pki_do_sign(ssh_session session,
ssh_buffer sigbuf,
- const ssh_key privkey)
+ const ssh_key privkey,
+ enum ssh_digest_e hash_type)
{
struct ssh_crypto_struct *crypto = NULL;
@@ -2161,11 +2158,13 @@ ssh_string ssh_pki_do_sign(ssh_session session,
ssh_string session_id = NULL;
ssh_buffer sign_input = NULL;
- enum ssh_digest_e hash_type;
-
int rc;
- if (privkey == NULL || !ssh_key_is_private(privkey)) {
+ if (session == NULL || sigbuf == NULL || privkey == NULL ||
+ !ssh_key_is_private(privkey))
+ {
+ SSH_LOG(SSH_LOG_TRACE, "Bad parameter provided to "
+ "ssh_pki_do_sign()");
return NULL;
}
@@ -2181,9 +2180,6 @@ ssh_string ssh_pki_do_sign(ssh_session session,
}
ssh_string_fill(session_id, crypto->session_id, crypto->digest_len);
- /* Get the hash type from the key type */
- hash_type = ssh_key_type_to_hash(session, privkey->type);
-
/* Fill the input */
sign_input = ssh_buffer_new();
if (sign_input == NULL) {
@@ -2200,52 +2196,14 @@ ssh_string ssh_pki_do_sign(ssh_session session,
}
/* Generate the signature */
- if (privkey->type == SSH_KEYTYPE_ED25519){
- sig = pki_do_sign(privkey,
- ssh_buffer_get(sign_input),
- ssh_buffer_get_len(sign_input));
- } else {
- unsigned char hash[SHA512_DIGEST_LEN] = {0};
- uint32_t hlen = 0;
- switch (hash_type) {
- case SSH_DIGEST_SHA256:
- sha256(ssh_buffer_get(sign_input), ssh_buffer_get_len(sign_input),
- hash);
- hlen = SHA256_DIGEST_LEN;
- break;
- case SSH_DIGEST_SHA384:
- sha384(ssh_buffer_get(sign_input), ssh_buffer_get_len(sign_input),
- hash);
- hlen = SHA384_DIGEST_LEN;
- break;
- case SSH_DIGEST_SHA512:
- sha512(ssh_buffer_get(sign_input), ssh_buffer_get_len(sign_input),
- hash);
- hlen = SHA512_DIGEST_LEN;
- break;
- case SSH_DIGEST_SHA1:
- case SSH_DIGEST_AUTO:
- sha1(ssh_buffer_get(sign_input), ssh_buffer_get_len(sign_input),
- hash);
- hlen = SHA_DIGEST_LEN;
- break;
- default:
- SSH_LOG(SSH_LOG_TRACE, "Unknown hash algorithm for type: %d",
- hash_type);
- goto end;
- }
- sig = pki_do_sign_hash(privkey, hash, hlen, hash_type);
- }
-
+ sig = pki_do_sign(privkey,
+ ssh_buffer_get(sign_input),
+ ssh_buffer_get_len(sign_input),
+ hash_type);
if (sig == NULL) {
goto end;
}
-#ifdef DEBUG_CRYPTO
- SSH_LOG(SSH_LOG_TRACE, "Generated signature for %s and hash_type = %d",
- privkey->type_c, hash_type);
-#endif
-
/* Convert the signature to blob */
rc = ssh_pki_export_signature_blob(sig, &sig_blob);
if (rc < 0) {
@@ -2355,52 +2313,14 @@ ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
}
/* Generate the signature */
- if (privkey->type == SSH_KEYTYPE_ED25519){
- sig = pki_do_sign(privkey,
- ssh_buffer_get(sign_input),
- ssh_buffer_get_len(sign_input));
- } else {
- unsigned char hash[SHA512_DIGEST_LEN] = {0};
- uint32_t hlen = 0;
- switch (hash_type) {
- case SSH_DIGEST_SHA256:
- sha256(ssh_buffer_get(sign_input), ssh_buffer_get_len(sign_input),
- hash);
- hlen = SHA256_DIGEST_LEN;
- break;
- case SSH_DIGEST_SHA384:
- sha384(ssh_buffer_get(sign_input), ssh_buffer_get_len(sign_input),
- hash);
- hlen = SHA384_DIGEST_LEN;
- break;
- case SSH_DIGEST_SHA512:
- sha512(ssh_buffer_get(sign_input), ssh_buffer_get_len(sign_input),
- hash);
- hlen = SHA512_DIGEST_LEN;
- break;
- case SSH_DIGEST_SHA1:
- case SSH_DIGEST_AUTO:
- sha1(ssh_buffer_get(sign_input), ssh_buffer_get_len(sign_input),
- hash);
- hlen = SHA_DIGEST_LEN;
- break;
- default:
- SSH_LOG(SSH_LOG_TRACE, "Unknown hash algorithm for type: %d",
- hash_type);
- goto end;
- }
- sig = pki_do_sign_hash(privkey, hash, hlen, hash_type);
- }
-
+ sig = pki_do_sign(privkey,
+ ssh_buffer_get(sign_input),
+ ssh_buffer_get_len(sign_input),
+ hash_type);
if (sig == NULL) {
goto end;
}
-#ifdef DEBUG_CRYPTO
- SSH_LOG(SSH_LOG_TRACE, "Generated signature for %s and hash_type = %d",
- privkey->type_c, hash_type);
-#endif
-
/* Convert the signature to blob */
rc = ssh_pki_export_signature_blob(sig, &sig_blob);
if (rc < 0) {