diff --git a/include/libssh/pki_priv.h b/include/libssh/pki_priv.h index b6d312b9..f90d7c86 100644 --- a/include/libssh/pki_priv.h +++ b/include/libssh/pki_priv.h @@ -59,12 +59,13 @@ int pki_signature_verify(ssh_session session, const ssh_signature sig, const ssh_key key, const unsigned char *hash, - size_t len); + size_t hlen); /* SSH Signing Functions */ ssh_signature pki_do_sign(const ssh_key privkey, const unsigned char *hash, size_t hlen); ssh_signature pki_do_sign_sessionid(const ssh_key key, - const unsigned char *hash); + const unsigned char *hash, + size_t hlen); #endif /* PKI_PRIV_H_ */ diff --git a/src/pki.c b/src/pki.c index 48cd98db..a5926f1e 100644 --- a/src/pki.c +++ b/src/pki.c @@ -1022,7 +1022,7 @@ int ssh_pki_signature_verify_blob(ssh_session session, unsigned char *digest, size_t dlen) { - unsigned char hash[SHA_DIGEST_LEN + 1] = {0}; + unsigned char hash[SHA_DIGEST_LEN] = {0}; ssh_signature sig; int rc; @@ -1038,10 +1038,10 @@ int ssh_pki_signature_verify_blob(ssh_session session, key->type_c); - sha1(digest, dlen, hash + 1); + sha1(digest, dlen, hash); #ifdef DEBUG_CRYPTO - ssh_print_hexa("Hash to be verified with dsa", hash + 1, SHA_DIGEST_LEN); + ssh_print_hexa("Hash to be verified with dsa", hash, SHA_DIGEST_LEN); #endif rc = pki_signature_verify(session, @@ -1063,7 +1063,7 @@ ssh_string ssh_pki_do_sign(ssh_session session, struct ssh_crypto_struct *crypto = session->current_crypto ? session->current_crypto : session->next_crypto; - unsigned char hash[SHA_DIGEST_LEN + 1] = {0}; + unsigned char hash[SHA_DIGEST_LEN] = {0}; ssh_signature sig; ssh_string sig_blob = NULL; ssh_string str = NULL; @@ -1089,11 +1089,10 @@ ssh_string ssh_pki_do_sign(ssh_session session, sha1_update(ctx, str, ssh_string_len(str) + 4); ssh_string_free(str); sha1_update(ctx, buffer_get_rest(sigbuf), buffer_get_rest_len(sigbuf)); - sha1_final(hash + 1, ctx); - hash[0] = 0; + sha1_final(hash, ctx); #ifdef DEBUG_CRYPTO - ssh_print_hexa("Hash being signed with dsa", hash + 1, SHA_DIGEST_LEN); + ssh_print_hexa("Hash being signed with dsa", hash, SHA_DIGEST_LEN); #endif sig = pki_do_sign(privkey, hash, SHA_DIGEST_LEN); @@ -1169,7 +1168,7 @@ ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session, struct ssh_crypto_struct *crypto = session->current_crypto ? session->current_crypto : session->next_crypto; - unsigned char hash[SHA_DIGEST_LEN + 1] = {0}; + unsigned char hash[SHA_DIGEST_LEN] = {0}; ssh_signature sig; ssh_string sig_blob; SHACTX ctx; @@ -1184,14 +1183,13 @@ ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session, return NULL; } sha1_update(ctx, crypto->session_id, SHA_DIGEST_LEN); - sha1_final(hash + 1, ctx); - hash[0] = 0; + sha1_final(hash, ctx); #ifdef DEBUG_CRYPTO - ssh_print_hexa("Hash being signed", hash + 1, SHA_DIGEST_LEN); + ssh_print_hexa("Hash being signed", hash, SHA_DIGEST_LEN); #endif - sig = pki_do_sign_sessionid(privkey, hash); + sig = pki_do_sign_sessionid(privkey, hash, SHA_DIGEST_LEN); if (sig == NULL) { return NULL; } diff --git a/src/pki_crypto.c b/src/pki_crypto.c index 7140a88c..a2c04b48 100644 --- a/src/pki_crypto.c +++ b/src/pki_crypto.c @@ -677,14 +677,14 @@ int pki_signature_verify(ssh_session session, const ssh_signature sig, const ssh_key key, const unsigned char *hash, - size_t len) + size_t hlen) { int rc; switch(key->type) { case SSH_KEYTYPE_DSS: - rc = DSA_do_verify(hash + 1, - len, + rc = DSA_do_verify(hash, + hlen, sig->dsa_sig, key->dsa); if (rc < 0) { @@ -698,8 +698,8 @@ int pki_signature_verify(ssh_session session, case SSH_KEYTYPE_RSA: case SSH_KEYTYPE_RSA1: rc = RSA_verify(NID_sha1, - hash + 1, - len, + hash, + hlen, string_data(sig->rsa_sig), ssh_string_len(sig->rsa_sig), key->rsa); @@ -734,7 +734,7 @@ ssh_signature pki_do_sign(const ssh_key privkey, switch(privkey->type) { case SSH_KEYTYPE_DSS: - sig->dsa_sig = DSA_do_sign(hash + 1, hlen, privkey->dsa); + sig->dsa_sig = DSA_do_sign(hash, hlen, privkey->dsa); if (sig->dsa_sig == NULL) { ssh_signature_free(sig); return NULL; @@ -748,7 +748,7 @@ ssh_signature pki_do_sign(const ssh_key privkey, break; case SSH_KEYTYPE_RSA: case SSH_KEYTYPE_RSA1: - sig->rsa_sig = _RSA_do_sign(hash + 1, hlen, privkey->rsa); + sig->rsa_sig = _RSA_do_sign(hash, hlen, privkey->rsa); if (sig->rsa_sig == NULL) { ssh_signature_free(sig); return NULL; @@ -766,7 +766,8 @@ ssh_signature pki_do_sign(const ssh_key privkey, #ifdef WITH_SERVER ssh_signature pki_do_sign_sessionid(const ssh_key key, - const unsigned char *hash) + const unsigned char *hash, + size_t hlen) { ssh_signature sig; @@ -778,7 +779,7 @@ ssh_signature pki_do_sign_sessionid(const ssh_key key, switch(key->type) { case SSH_KEYTYPE_DSS: - sig->dsa_sig = DSA_do_sign(hash + 1, SHA_DIGEST_LEN, key->dsa); + sig->dsa_sig = DSA_do_sign(hash, hlen, key->dsa); if (sig->dsa_sig == NULL) { ssh_signature_free(sig); return NULL; @@ -786,7 +787,7 @@ ssh_signature pki_do_sign_sessionid(const ssh_key key, break; case SSH_KEYTYPE_RSA: case SSH_KEYTYPE_RSA1: - sig->rsa_sig = _RSA_do_sign(hash + 1, SHA_DIGEST_LEN, key->rsa); + sig->rsa_sig = _RSA_do_sign(hash, hlen, key->rsa); if (sig->rsa_sig == NULL) { ssh_signature_free(sig); return NULL; diff --git a/src/pki_gcrypt.c b/src/pki_gcrypt.c index 5e10773e..78d92cfa 100644 --- a/src/pki_gcrypt.c +++ b/src/pki_gcrypt.c @@ -1322,19 +1322,23 @@ int pki_signature_verify(ssh_session session, const ssh_signature sig, const ssh_key key, const unsigned char *hash, - size_t len) + size_t hlen) { + unsigned char ghash[hlen + 1]; gcry_sexp_t sexp; gcry_error_t err; switch(key->type) { case SSH_KEYTYPE_DSS: - if(hash[1] < 0x80) { - hash = hash + 1; - } else { - len = len + 1; + /* That is to mark the number as positive */ + if(hash[0] >= 0x80) { + memcpy(ghash + 1, hash, hlen); + ghash[0] = 0; + hash = ghash; + hlen += 1; } - err = gcry_sexp_build(&sexp, NULL, "%b", len, hash); + + err = gcry_sexp_build(&sexp, NULL, "%b", hlen, hash); if (err) { ssh_set_error(session, SSH_FATAL, @@ -1359,7 +1363,7 @@ int pki_signature_verify(ssh_session session, err = gcry_sexp_build(&sexp, NULL, "(data(flags pkcs1)(hash sha1 %b))", - len, hash + 1); + hlen, hash); if (err) { ssh_set_error(session, SSH_FATAL, @@ -1392,6 +1396,7 @@ int pki_signature_verify(ssh_session session, ssh_signature pki_do_sign(const ssh_key privkey, const unsigned char *hash, size_t hlen) { + unsigned char ghash[hlen + 1]; ssh_signature sig; gcry_sexp_t sexp; gcry_error_t err; @@ -1404,11 +1409,14 @@ ssh_signature pki_do_sign(const ssh_key privkey, switch (privkey->type) { case SSH_KEYTYPE_DSS: - if(hash[1] < 0x80) { - hash = hash + 1; - } else { - hlen = hlen + 1; + /* That is to mark the number as positive */ + if(hash[0] >= 0x80) { + memcpy(ghash + 1, hash, hlen); + ghash[0] = 0; + hash = ghash; + hlen += 1; } + err = gcry_sexp_build(&sexp, NULL, "%b", hlen, hash); if (err) { ssh_signature_free(sig); @@ -1428,7 +1436,7 @@ ssh_signature pki_do_sign(const ssh_key privkey, NULL, "(data(flags pkcs1)(hash sha1 %b))", hlen, - hash + 1); + hash); if (err) { ssh_signature_free(sig); return NULL; @@ -1452,12 +1460,13 @@ ssh_signature pki_do_sign(const ssh_key privkey, #ifdef WITH_SERVER ssh_signature pki_do_sign_sessionid(const ssh_key key, - const unsigned char *hash) + const unsigned char *hash, + size_t hlen) { + unsigned char ghash[hlen + 1]; ssh_signature sig; gcry_sexp_t sexp; gcry_error_t err; - size_t len; sig = ssh_signature_new(); if (sig == NULL) { @@ -1467,17 +1476,15 @@ ssh_signature pki_do_sign_sessionid(const ssh_key key, switch(key->type) { case SSH_KEYTYPE_DSS: - len = SHA_DIGEST_LEN; - if(hash[1] < 0x80) { - hash = hash + 1; - } else { - len = len + 1; + /* That is to mark the number as positive */ + if(hash[0] >= 0x80) { + memcpy(ghash + 1, hash, hlen); + ghash[0] = 0; + hash = ghash; + hlen += 1; } - err = gcry_sexp_build(&sexp, - NULL, - "%b", - len, - hash); + + err = gcry_sexp_build(&sexp, NULL, "%b", hlen, hash); if (err) { ssh_signature_free(sig); return NULL; @@ -1494,8 +1501,8 @@ ssh_signature pki_do_sign_sessionid(const ssh_key key, err = gcry_sexp_build(&sexp, NULL, "(data(flags pkcs1)(hash sha1 %b))", - SHA_DIGEST_LEN, - hash + 1); + hlen, + hash); if (err) { ssh_signature_free(sig); return NULL;