diff --git a/docs/HACKING-CRYPTO b/docs/HACKING-CRYPTO index 694cd4d8..1ef6c449 100644 --- a/docs/HACKING-CRYPTO +++ b/docs/HACKING-CRYPTO @@ -98,20 +98,22 @@ int libssh2_sha1_init(libssh2_sha1_ctx *x); Initializes the SHA-1 computation context at x. Returns 1 for success and 0 for failure -void libssh2_sha1_update(libssh2_sha1_ctx ctx, - const unsigned char *data, - size_t len); +int libssh2_sha1_update(libssh2_sha1_ctx ctx, + const unsigned char *data, + size_t len); Continue computation of SHA-1 on len bytes at data using context ctx. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. +Must return 1 for success and 0 for failure. -void libssh2_sha1_final(libssh2_sha1_ctx ctx, - unsigned char output[SHA_DIGEST_LEN]); +int libssh2_sha1_final(libssh2_sha1_ctx ctx, + unsigned char output[SHA_DIGEST_LEN]); Get the computed SHA-1 signature from context ctx and store it into the output buffer. Release the context. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. +Must return 1 for success and 0 for failure. int libssh2_hmac_sha1_init(libssh2_hmac_ctx *ctx, const void *key, @@ -133,19 +135,21 @@ int libssh2_sha256_init(libssh2_sha256_ctx *x); Initializes the SHA-256 computation context at x. Returns 1 for success and 0 for failure -void libssh2_sha256_update(libssh2_sha256_ctx ctx, - const unsigned char *data, - size_t len); +int libssh2_sha256_update(libssh2_sha256_ctx ctx, + const unsigned char *data, + size_t len); Continue computation of SHA-256 on len bytes at data using context ctx. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. +Must return 1 for success and 0 for failure. -void libssh2_sha256_final(libssh2_sha256_ctx ctx, - unsigned char output[SHA256_DIGEST_LENGTH]); +int libssh2_sha256_final(libssh2_sha256_ctx ctx, + unsigned char output[SHA256_DIGEST_LENGTH]); Gets the computed SHA-256 signature from context ctx into the output buffer. Release the context. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. +Must return 1 for success and 0 for failure. int libssh2_sha256(const unsigned char *message, size_t len, @@ -179,19 +183,21 @@ int libssh2_sha384_init(libssh2_sha384_ctx *x); Initializes the SHA-384 computation context at x. Returns 1 for success and 0 for failure -void libssh2_sha384_update(libssh2_sha384_ctx ctx, - const unsigned char *data, - size_t len); +int libssh2_sha384_update(libssh2_sha384_ctx ctx, + const unsigned char *data, + size_t len); Continue computation of SHA-384 on len bytes at data using context ctx. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. +Must return 1 for success and 0 for failure. -void libssh2_sha384_final(libssh2_sha384_ctx ctx, - unsigned char output[SHA384_DIGEST_LENGTH]); +int libssh2_sha384_final(libssh2_sha384_ctx ctx, + unsigned char output[SHA384_DIGEST_LENGTH]); Gets the computed SHA-384 signature from context ctx into the output buffer. Release the context. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. +Must return 1 for success and 0 for failure. int libssh2_sha384(const unsigned char *message, size_t len, @@ -213,19 +219,21 @@ int libssh2_sha512_init(libssh2_sha512_ctx *x); Initializes the SHA-512 computation context at x. Returns 1 for success and 0 for failure -void libssh2_sha512_update(libssh2_sha512_ctx ctx, - const unsigned char *data, - size_t len); +int libssh2_sha512_update(libssh2_sha512_ctx ctx, + const unsigned char *data, + size_t len); Continue computation of SHA-512 on len bytes at data using context ctx. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. +Must return 1 for success and 0 for failure. -void libssh2_sha512_final(libssh2_sha512_ctx ctx, - unsigned char output[SHA512_DIGEST_LENGTH]); +int libssh2_sha512_final(libssh2_sha512_ctx ctx, + unsigned char output[SHA512_DIGEST_LENGTH]); Gets the computed SHA-512 signature from context ctx into the output buffer. Release the context. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. +Must return 1 for success and 0 for failure. int libssh2_sha512(const unsigned char *message, size_t len, @@ -261,20 +269,22 @@ int libssh2_md5_init(libssh2_md5_ctx *x); Initializes the MD5 computation context at x. Returns 1 for success and 0 for failure -void libssh2_md5_update(libssh2_md5_ctx ctx, - const unsigned char *data, - size_t len); +int libssh2_md5_update(libssh2_md5_ctx ctx, + const unsigned char *data, + size_t len); Continues computation of MD5 on len bytes at data using context ctx. Returns 1 for success and 0 for failure. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. +Must return 1 for success and 0 for failure. -void libssh2_md5_final(libssh2_md5_ctx ctx, - unsigned char output[MD5_DIGEST_LENGTH]); +int libssh2_md5_final(libssh2_md5_ctx ctx, + unsigned char output[MD5_DIGEST_LENGTH]); Gets the computed MD5 signature from context ctx into the output buffer. Release the context. Note: if the ctx parameter is modified by the underlying code, this procedure must be implemented as a macro to map ctx --> &ctx. +Must return 1 for success and 0 for failure. int libssh2_hmac_md5_init(libssh2_hmac_ctx *ctx, const void *key, diff --git a/include/libssh2.h b/include/libssh2.h index 77437429..8bc8a138 100644 --- a/include/libssh2.h +++ b/include/libssh2.h @@ -589,6 +589,7 @@ typedef struct _LIBSSH2_POLLFD { #define LIBSSH2_ERROR_ALGO_UNSUPPORTED -51 #define LIBSSH2_ERROR_MAC_FAILURE -52 #define LIBSSH2_ERROR_HASH_INIT -53 +#define LIBSSH2_ERROR_HASH_CALC -54 /* this is a define to provide the old (<= 1.2.7) name */ #define LIBSSH2_ERROR_BANNER_NONE LIBSSH2_ERROR_BANNER_RECV diff --git a/src/bcrypt_pbkdf.c b/src/bcrypt_pbkdf.c index 5da5b92f..414c5e4e 100644 --- a/src/bcrypt_pbkdf.c +++ b/src/bcrypt_pbkdf.c @@ -127,12 +127,12 @@ bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt, memcpy(countsalt, salt, saltlen); /* collapse password */ - if(!libssh2_sha512_init(&ctx)) { + if(!libssh2_sha512_init(&ctx) || + !libssh2_sha512_update(ctx, pass, passlen) || + !libssh2_sha512_final(ctx, sha2pass)) { free(countsalt); return -1; } - libssh2_sha512_update(ctx, pass, passlen); - libssh2_sha512_final(ctx, sha2pass); /* generate key, sizeof(out) at a time */ for(count = 1; keylen > 0; count++) { @@ -142,26 +142,26 @@ bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt, countsalt[saltlen + 3] = count & 0xff; /* first round, salt is salt */ - if(!libssh2_sha512_init(&ctx)) { + if(!libssh2_sha512_init(&ctx) || + !libssh2_sha512_update(ctx, countsalt, saltlen + 4) || + !libssh2_sha512_final(ctx, sha2salt)) { _libssh2_explicit_zero(out, sizeof(out)); free(countsalt); return -1; } - libssh2_sha512_update(ctx, countsalt, saltlen + 4); - libssh2_sha512_final(ctx, sha2salt); bcrypt_hash(sha2pass, sha2salt, tmpout); memcpy(out, tmpout, sizeof(out)); for(i = 1; i < rounds; i++) { /* subsequent rounds, salt is previous output */ - if(!libssh2_sha512_init(&ctx)) { + if(!libssh2_sha512_init(&ctx) || + !libssh2_sha512_update(ctx, tmpout, sizeof(tmpout)) || + !libssh2_sha512_final(ctx, sha2salt)) { _libssh2_explicit_zero(out, sizeof(out)); free(countsalt); return -1; } - libssh2_sha512_update(ctx, tmpout, sizeof(tmpout)); - libssh2_sha512_final(ctx, sha2salt); bcrypt_hash(sha2pass, sha2salt, tmpout); for(j = 0; j < sizeof(out); j++) diff --git a/src/hostkey.c b/src/hostkey.c index 50a88a3d..b28b4e69 100644 --- a/src/hostkey.c +++ b/src/hostkey.c @@ -242,13 +242,18 @@ hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session, unsigned char hash[SHA_DIGEST_LENGTH]; libssh2_sha1_ctx ctx; - if(!libssh2_sha1_init(&ctx)) + if(!libssh2_sha1_init(&ctx)) { + return -1; + } + for(i = 0; i < veccount; i++) { + if(!libssh2_sha1_update(ctx, + datavec[i].iov_base, datavec[i].iov_len)) { + return -1; + } + } + if(!libssh2_sha1_final(ctx, hash)) { return -1; - - for(i = 0; i < veccount; i++) { - libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len); } - libssh2_sha1_final(ctx, hash); ret = _libssh2_rsa_sha1_sign(session, rsactx, hash, SHA_DIGEST_LENGTH, signature, signature_len); @@ -318,9 +323,14 @@ hostkey_method_ssh_rsa_sha2_256_signv(LIBSSH2_SESSION * session, return -1; } for(i = 0; i < veccount; i++) { - libssh2_sha256_update(ctx, datavec[i].iov_base, datavec[i].iov_len); + if(!libssh2_sha256_update(ctx, + datavec[i].iov_base, datavec[i].iov_len)) { + return -1; + } + } + if(!libssh2_sha256_final(ctx, hash)) { + return -1; } - libssh2_sha256_final(ctx, hash); ret = _libssh2_rsa_sha2_sign(session, rsactx, hash, SHA256_DIGEST_LENGTH, signature, signature_len); @@ -388,9 +398,14 @@ hostkey_method_ssh_rsa_sha2_512_signv(LIBSSH2_SESSION * session, return -1; } for(i = 0; i < veccount; i++) { - libssh2_sha512_update(ctx, datavec[i].iov_base, datavec[i].iov_len); + if(!libssh2_sha512_update(ctx, + datavec[i].iov_base, datavec[i].iov_len)) { + return -1; + } + } + if(!libssh2_sha512_final(ctx, hash)) { + return -1; } - libssh2_sha512_final(ctx, hash); ret = _libssh2_rsa_sha2_sign(session, rsactx, hash, SHA512_DIGEST_LENGTH, signature, signature_len); @@ -675,9 +690,14 @@ hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session, *signature_len = 2 * SHA_DIGEST_LENGTH; for(i = 0; i < veccount; i++) { - libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len); + if(!libssh2_sha1_update(ctx, + datavec[i].iov_base, datavec[i].iov_len)) { + return -1; + } + } + if(!libssh2_sha1_final(ctx, hash)) { + return -1; } - libssh2_sha1_final(ctx, hash); if(_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, *signature)) { LIBSSH2_FREE(session, *signature); @@ -916,23 +936,33 @@ hostkey_method_ssh_ecdsa_sig_verify(LIBSSH2_SESSION * session, } -#define LIBSSH2_HOSTKEY_METHOD_EC_SIGNV_HASH(digest_type) \ - do { \ - unsigned char hash[SHA##digest_type##_DIGEST_LENGTH]; \ - libssh2_sha##digest_type##_ctx ctx; \ - int i; \ - if(!libssh2_sha##digest_type##_init(&ctx)) { \ - ret = -1; \ - break; \ - } \ - for(i = 0; i < veccount; i++) { \ - libssh2_sha##digest_type##_update(ctx, datavec[i].iov_base, \ - datavec[i].iov_len); \ - } \ - libssh2_sha##digest_type##_final(ctx, hash); \ - ret = _libssh2_ecdsa_sign(session, ec_ctx, hash, \ - SHA##digest_type##_DIGEST_LENGTH, \ - signature, signature_len); \ +#define LIBSSH2_HOSTKEY_METHOD_EC_SIGNV_HASH(digest_type) \ + do { \ + unsigned char hash[SHA##digest_type##_DIGEST_LENGTH]; \ + libssh2_sha##digest_type##_ctx ctx; \ + int i; \ + if(!libssh2_sha##digest_type##_init(&ctx)) { \ + ret = -1; \ + break; \ + } \ + for(i = 0; i < veccount; i++) { \ + if(!libssh2_sha##digest_type##_update(ctx, \ + datavec[i].iov_base, \ + datavec[i].iov_len)) { \ + ret = -1; \ + break; \ + } \ + } \ + if(ret == -1) { \ + break; \ + } \ + if(!libssh2_sha##digest_type##_final(ctx, hash)) { \ + ret = -1; \ + break; \ + } \ + ret = _libssh2_ecdsa_sign(session, ec_ctx, hash, \ + SHA##digest_type##_DIGEST_LENGTH, \ + signature, signature_len); \ } while(0) diff --git a/src/kex.c b/src/kex.c index 98aed88d..8c65a0fe 100644 --- a/src/kex.c +++ b/src/kex.c @@ -81,26 +81,40 @@ do { \ } \ if(value) \ while(len < (size_t)reqlen) { \ - if(!libssh2_sha##digest_type##_init(&hash)) { \ + if(!libssh2_sha##digest_type##_init(&hash) || \ + !libssh2_sha##digest_type##_update(hash, \ + exchange_state->k_value, \ + exchange_state->k_value_len) || \ + !libssh2_sha##digest_type##_update(hash, \ + exchange_state->h_sig_comp, \ + SHA##digest_type##_DIGEST_LENGTH)) { \ LIBSSH2_FREE(session, value); \ value = NULL; \ break; \ } \ - libssh2_sha##digest_type##_update(hash, \ - exchange_state->k_value, \ - exchange_state->k_value_len); \ - libssh2_sha##digest_type##_update(hash, \ - exchange_state->h_sig_comp, \ - SHA##digest_type##_DIGEST_LENGTH); \ if(len > 0) { \ - libssh2_sha##digest_type##_update(hash, value, len); \ + if(!libssh2_sha##digest_type##_update(hash, value, len)) { \ + LIBSSH2_FREE(session, value); \ + value = NULL; \ + break; \ + } \ } \ else { \ - libssh2_sha##digest_type##_update(hash, (version), 1); \ - libssh2_sha##digest_type##_update(hash, session->session_id,\ - session->session_id_len); \ + if(!libssh2_sha##digest_type##_update(hash, \ + (version), 1) || \ + !libssh2_sha##digest_type##_update(hash, \ + session->session_id, \ + session->session_id_len)) { \ + LIBSSH2_FREE(session, value); \ + value = NULL; \ + break; \ + } \ + } \ + if(!libssh2_sha##digest_type##_final(hash, (value) + len)) { \ + LIBSSH2_FREE(session, value); \ + value = NULL; \ + break; \ } \ - libssh2_sha##digest_type##_final(hash, (value) + len); \ len += SHA##digest_type##_DIGEST_LENGTH; \ } \ } while(0) @@ -134,56 +148,58 @@ static int _libssh2_sha_algo_ctx_init(int sha_algo, void *ctx) return 0; } -static void _libssh2_sha_algo_ctx_update(int sha_algo, void *ctx, - void *data, size_t len) +static int _libssh2_sha_algo_ctx_update(int sha_algo, void *ctx, + void *data, size_t len) { if(sha_algo == 512) { libssh2_sha512_ctx *_ctx = (libssh2_sha512_ctx*)ctx; - libssh2_sha512_update(*_ctx, data, len); + return libssh2_sha512_update(*_ctx, data, len); } else if(sha_algo == 384) { libssh2_sha384_ctx *_ctx = (libssh2_sha384_ctx*)ctx; - libssh2_sha384_update(*_ctx, data, len); + return libssh2_sha384_update(*_ctx, data, len); } else if(sha_algo == 256) { libssh2_sha256_ctx *_ctx = (libssh2_sha256_ctx*)ctx; - libssh2_sha256_update(*_ctx, data, len); + return libssh2_sha256_update(*_ctx, data, len); } else if(sha_algo == 1) { libssh2_sha1_ctx *_ctx = (libssh2_sha1_ctx*)ctx; - libssh2_sha1_update(*_ctx, data, len); + return libssh2_sha1_update(*_ctx, data, len); } else { #ifdef LIBSSH2DEBUG assert(0); #endif } + return 0; } -static void _libssh2_sha_algo_ctx_final(int sha_algo, void *ctx, - void *hash) +static int _libssh2_sha_algo_ctx_final(int sha_algo, void *ctx, + void *hash) { if(sha_algo == 512) { libssh2_sha512_ctx *_ctx = (libssh2_sha512_ctx*)ctx; - libssh2_sha512_final(*_ctx, hash); + return libssh2_sha512_final(*_ctx, hash); } else if(sha_algo == 384) { libssh2_sha384_ctx *_ctx = (libssh2_sha384_ctx*)ctx; - libssh2_sha384_final(*_ctx, hash); + return libssh2_sha384_final(*_ctx, hash); } else if(sha_algo == 256) { libssh2_sha256_ctx *_ctx = (libssh2_sha256_ctx*)ctx; - libssh2_sha256_final(*_ctx, hash); + return libssh2_sha256_final(*_ctx, hash); } else if(sha_algo == 1) { libssh2_sha1_ctx *_ctx = (libssh2_sha1_ctx*)ctx; - libssh2_sha1_final(*_ctx, hash); + return libssh2_sha1_final(*_ctx, hash); } else { #ifdef LIBSSH2DEBUG assert(0); #endif } + return 0; } static void _libssh2_sha_algo_value_hash(int sha_algo, @@ -364,6 +380,7 @@ static int diffie_hellman_sha_algo(LIBSSH2_SESSION *session, struct string_buf buf; size_t host_key_len; int err; + int hok; rc = _libssh2_packet_require(session, packet_type_reply, &exchange_state->s_packet, @@ -406,11 +423,11 @@ static int diffie_hellman_sha_algo(LIBSSH2_SESSION *session, { libssh2_md5_ctx fingerprint_ctx; - if(libssh2_md5_init(&fingerprint_ctx)) { - libssh2_md5_update(fingerprint_ctx, session->server_hostkey, - session->server_hostkey_len); - libssh2_md5_final(fingerprint_ctx, - session->server_hostkey_md5); + if(libssh2_md5_init(&fingerprint_ctx) && + libssh2_md5_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len) && + libssh2_md5_final(fingerprint_ctx, + session->server_hostkey_md5)) { session->server_hostkey_md5_valid = TRUE; } else { @@ -434,11 +451,11 @@ static int diffie_hellman_sha_algo(LIBSSH2_SESSION *session, { libssh2_sha1_ctx fingerprint_ctx; - if(libssh2_sha1_init(&fingerprint_ctx)) { - libssh2_sha1_update(fingerprint_ctx, session->server_hostkey, - session->server_hostkey_len); - libssh2_sha1_final(fingerprint_ctx, - session->server_hostkey_sha1); + if(libssh2_sha1_init(&fingerprint_ctx) && + libssh2_sha1_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len) && + libssh2_sha1_final(fingerprint_ctx, + session->server_hostkey_sha1)) { session->server_hostkey_sha1_valid = TRUE; } else { @@ -461,11 +478,11 @@ static int diffie_hellman_sha_algo(LIBSSH2_SESSION *session, { libssh2_sha256_ctx fingerprint_ctx; - if(libssh2_sha256_init(&fingerprint_ctx)) { - libssh2_sha256_update(fingerprint_ctx, session->server_hostkey, - session->server_hostkey_len); - libssh2_sha256_final(fingerprint_ctx, - session->server_hostkey_sha256); + if(libssh2_sha256_init(&fingerprint_ctx) && + libssh2_sha256_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len) && + libssh2_sha256_final(fingerprint_ctx, + session->server_hostkey_sha256)) { session->server_hostkey_sha256_valid = TRUE; } else { @@ -546,57 +563,61 @@ static int diffie_hellman_sha_algo(LIBSSH2_SESSION *session, "Unable to initialize hash context"); goto clean_exit; } + hok = 1; if(session->local.banner) { _libssh2_htonu32(exchange_state->h_sig_comp, (uint32_t)(strlen((char *) session->local.banner) - 2)); - _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, - exchange_state->h_sig_comp, 4); - _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, - session->local.banner, + hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, + exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, + exchange_hash_ctx, + session->local.banner, strlen((char *) session->local.banner) - 2); } else { _libssh2_htonu32(exchange_state->h_sig_comp, sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); - _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, - exchange_state->h_sig_comp, 4); - _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, - (unsigned char *) - LIBSSH2_SSH_DEFAULT_BANNER, + hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, + exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, + exchange_hash_ctx, + (unsigned char *)LIBSSH2_SSH_DEFAULT_BANNER, sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); } _libssh2_htonu32(exchange_state->h_sig_comp, (uint32_t)strlen((char *) session->remote.banner)); - _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, - exchange_state->h_sig_comp, 4); - _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, - session->remote.banner, - strlen((char *) session->remote.banner)); + hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, + session->remote.banner, + strlen((char *)session->remote.banner)); _libssh2_htonu32(exchange_state->h_sig_comp, (uint32_t)session->local.kexinit_len); - _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, - exchange_state->h_sig_comp, 4); - _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, - session->local.kexinit, - session->local.kexinit_len); + hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, + session->local.kexinit, + session->local.kexinit_len); _libssh2_htonu32(exchange_state->h_sig_comp, (uint32_t)session->remote.kexinit_len); - _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, - exchange_state->h_sig_comp, 4); - _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, - session->remote.kexinit, - session->remote.kexinit_len); + hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, + session->remote.kexinit, + session->remote.kexinit_len); _libssh2_htonu32(exchange_state->h_sig_comp, session->server_hostkey_len); - _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, - exchange_state->h_sig_comp, 4); - _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, - session->server_hostkey, - session->server_hostkey_len); + hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, + session->server_hostkey, + session->server_hostkey_len); if(packet_type_init == SSH_MSG_KEX_DH_GEX_INIT) { /* diffie-hellman-group-exchange hashes additional fields */ @@ -606,33 +627,41 @@ static int diffie_hellman_sha_algo(LIBSSH2_SESSION *session, LIBSSH2_DH_GEX_OPTGROUP); _libssh2_htonu32(exchange_state->h_sig_comp + 8, LIBSSH2_DH_GEX_MAXGROUP); - _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, - exchange_state->h_sig_comp, 12); + hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, + exchange_hash_ctx, + exchange_state->h_sig_comp, + 12); } if(midhash) { - _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, - midhash, midhash_len); + hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, + exchange_hash_ctx, + midhash, midhash_len); } - _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, - exchange_state->e_packet + 1, - exchange_state->e_packet_len - 1); + hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, + exchange_state->e_packet + 1, + exchange_state->e_packet_len - 1); _libssh2_htonu32(exchange_state->h_sig_comp, (uint32_t)exchange_state->f_value_len); - _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, - exchange_state->h_sig_comp, 4); - _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, - exchange_state->f_value, - exchange_state->f_value_len); + hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, + exchange_state->f_value, + exchange_state->f_value_len); - _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, - exchange_state->k_value, - exchange_state->k_value_len); + hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx, + exchange_state->k_value, + exchange_state->k_value_len); - _libssh2_sha_algo_ctx_final(sha_algo_value, exchange_hash_ctx, - exchange_state->h_sig_comp); + if(!hok || + !_libssh2_sha_algo_ctx_final(sha_algo_value, exchange_hash_ctx, + exchange_state->h_sig_comp)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HASH_CALC, + "kex: failed to calculate hash"); + goto clean_exit; + } err = session->hostkey->sig_verify(session, exchange_state->h_sig, @@ -1601,87 +1630,91 @@ dh_gex_clean_exit: #define LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(digest_type) \ do { \ libssh2_sha##digest_type##_ctx ctx; \ + int hok; \ if(!libssh2_sha##digest_type##_init(&ctx)) { \ rc = -1; \ break; \ } \ exchange_state->exchange_hash = (void *)&ctx; \ + hok = 1; \ if(session->local.banner) { \ _libssh2_htonu32(exchange_state->h_sig_comp, \ (uint32_t)(strlen((char *) session->local.banner) - 2)); \ - libssh2_sha##digest_type##_update(ctx, \ - exchange_state->h_sig_comp, 4); \ - libssh2_sha##digest_type##_update(ctx, \ - (char *) session->local.banner, \ - strlen((char *) \ - session->local.banner) \ - - 2); \ + hok &= libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, \ + 4); \ + hok &= libssh2_sha##digest_type##_update(ctx, \ + (char *)session->local.banner, \ + strlen((char *)session->local.banner) \ + - 2); \ } \ else { \ _libssh2_htonu32(exchange_state->h_sig_comp, \ sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); \ - libssh2_sha##digest_type##_update(ctx, \ + hok &= libssh2_sha##digest_type##_update(ctx, \ exchange_state->h_sig_comp, 4); \ - libssh2_sha##digest_type##_update(ctx, \ - LIBSSH2_SSH_DEFAULT_BANNER, \ + hok &= libssh2_sha##digest_type##_update(ctx, \ + LIBSSH2_SSH_DEFAULT_BANNER, \ sizeof(LIBSSH2_SSH_DEFAULT_BANNER) \ - 1); \ } \ \ _libssh2_htonu32(exchange_state->h_sig_comp, \ (uint32_t)strlen((char *) session->remote.banner)); \ - libssh2_sha##digest_type##_update(ctx, \ - exchange_state->h_sig_comp, 4); \ - libssh2_sha##digest_type##_update(ctx, \ - session->remote.banner, \ - strlen((char *) \ - session->remote.banner)); \ + hok &= libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + hok &= libssh2_sha##digest_type##_update(ctx, session->remote.banner, \ + strlen((char *)session->remote.banner)); \ \ _libssh2_htonu32(exchange_state->h_sig_comp, \ (uint32_t)session->local.kexinit_len); \ - libssh2_sha##digest_type##_update(ctx, \ - exchange_state->h_sig_comp, 4); \ - libssh2_sha##digest_type##_update(ctx, \ - session->local.kexinit, \ - session->local.kexinit_len); \ + hok &= libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + hok &= libssh2_sha##digest_type##_update(ctx, \ + session->local.kexinit, \ + session->local.kexinit_len); \ \ _libssh2_htonu32(exchange_state->h_sig_comp, \ (uint32_t)session->remote.kexinit_len); \ - libssh2_sha##digest_type##_update(ctx, \ - exchange_state->h_sig_comp, 4); \ - libssh2_sha##digest_type##_update(ctx, \ - session->remote.kexinit, \ - session->remote.kexinit_len); \ + hok &= libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + hok &= libssh2_sha##digest_type##_update(ctx, \ + session->remote.kexinit, \ + session->remote.kexinit_len); \ \ _libssh2_htonu32(exchange_state->h_sig_comp, \ session->server_hostkey_len); \ - libssh2_sha##digest_type##_update(ctx, \ - exchange_state->h_sig_comp, 4); \ - libssh2_sha##digest_type##_update(ctx, \ - session->server_hostkey, \ - session->server_hostkey_len); \ + hok &= libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + hok &= libssh2_sha##digest_type##_update(ctx, \ + session->server_hostkey, \ + session->server_hostkey_len); \ \ _libssh2_htonu32(exchange_state->h_sig_comp, \ (uint32_t)public_key_len); \ - libssh2_sha##digest_type##_update(ctx, \ - exchange_state->h_sig_comp, 4); \ - libssh2_sha##digest_type##_update(ctx, \ - public_key, \ - public_key_len); \ + hok &= libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + hok &= libssh2_sha##digest_type##_update(ctx, \ + public_key, \ + public_key_len); \ \ _libssh2_htonu32(exchange_state->h_sig_comp, \ (uint32_t)server_public_key_len); \ - libssh2_sha##digest_type##_update(ctx, \ - exchange_state->h_sig_comp, 4); \ - libssh2_sha##digest_type##_update(ctx, \ - server_public_key, \ - server_public_key_len); \ + hok &= libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + hok &= libssh2_sha##digest_type##_update(ctx, \ + server_public_key, \ + server_public_key_len); \ \ - libssh2_sha##digest_type##_update(ctx, \ - exchange_state->k_value, \ - exchange_state->k_value_len); \ + hok &= libssh2_sha##digest_type##_update(ctx, \ + exchange_state->k_value, \ + exchange_state->k_value_len); \ \ - libssh2_sha##digest_type##_final(ctx, exchange_state->h_sig_comp); \ + if(!hok || \ + !libssh2_sha##digest_type##_final(ctx, exchange_state->h_sig_comp)) { \ + rc = -1; \ + break; \ + } \ \ if(session->hostkey-> \ sig_verify(session, exchange_state->h_sig, \ @@ -1776,11 +1809,11 @@ static int ecdh_sha2_nistp(LIBSSH2_SESSION *session, libssh2_curve_type type, { libssh2_md5_ctx fingerprint_ctx; - if(libssh2_md5_init(&fingerprint_ctx)) { - libssh2_md5_update(fingerprint_ctx, session->server_hostkey, - session->server_hostkey_len); - libssh2_md5_final(fingerprint_ctx, - session->server_hostkey_md5); + if(libssh2_md5_init(&fingerprint_ctx) && + libssh2_md5_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len) && + libssh2_md5_final(fingerprint_ctx, + session->server_hostkey_md5)) { session->server_hostkey_md5_valid = TRUE; } else { @@ -1804,11 +1837,11 @@ static int ecdh_sha2_nistp(LIBSSH2_SESSION *session, libssh2_curve_type type, { libssh2_sha1_ctx fingerprint_ctx; - if(libssh2_sha1_init(&fingerprint_ctx)) { - libssh2_sha1_update(fingerprint_ctx, session->server_hostkey, - session->server_hostkey_len); - libssh2_sha1_final(fingerprint_ctx, - session->server_hostkey_sha1); + if(libssh2_sha1_init(&fingerprint_ctx) && + libssh2_sha1_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len) && + libssh2_sha1_final(fingerprint_ctx, + session->server_hostkey_sha1)) { session->server_hostkey_sha1_valid = TRUE; } else { @@ -1832,11 +1865,11 @@ static int ecdh_sha2_nistp(LIBSSH2_SESSION *session, libssh2_curve_type type, { libssh2_sha256_ctx fingerprint_ctx; - if(libssh2_sha256_init(&fingerprint_ctx)) { - libssh2_sha256_update(fingerprint_ctx, session->server_hostkey, - session->server_hostkey_len); - libssh2_sha256_final(fingerprint_ctx, - session->server_hostkey_sha256); + if(libssh2_sha256_init(&fingerprint_ctx) && + libssh2_sha256_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len) && + libssh2_sha256_final(fingerprint_ctx, + session->server_hostkey_sha256)) { session->server_hostkey_sha256_valid = TRUE; } else { @@ -2407,11 +2440,11 @@ curve25519_sha256(LIBSSH2_SESSION *session, unsigned char *data, { libssh2_md5_ctx fingerprint_ctx; - if(libssh2_md5_init(&fingerprint_ctx)) { - libssh2_md5_update(fingerprint_ctx, session->server_hostkey, - session->server_hostkey_len); - libssh2_md5_final(fingerprint_ctx, - session->server_hostkey_md5); + if(libssh2_md5_init(&fingerprint_ctx) && + libssh2_md5_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len) && + libssh2_md5_final(fingerprint_ctx, + session->server_hostkey_md5)) { session->server_hostkey_md5_valid = TRUE; } else { @@ -2435,11 +2468,11 @@ curve25519_sha256(LIBSSH2_SESSION *session, unsigned char *data, { libssh2_sha1_ctx fingerprint_ctx; - if(libssh2_sha1_init(&fingerprint_ctx)) { - libssh2_sha1_update(fingerprint_ctx, session->server_hostkey, - session->server_hostkey_len); - libssh2_sha1_final(fingerprint_ctx, - session->server_hostkey_sha1); + if(libssh2_sha1_init(&fingerprint_ctx) && + libssh2_sha1_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len) && + libssh2_sha1_final(fingerprint_ctx, + session->server_hostkey_sha1)) { session->server_hostkey_sha1_valid = TRUE; } else { @@ -2463,11 +2496,11 @@ curve25519_sha256(LIBSSH2_SESSION *session, unsigned char *data, { libssh2_sha256_ctx fingerprint_ctx; - if(libssh2_sha256_init(&fingerprint_ctx)) { - libssh2_sha256_update(fingerprint_ctx, session->server_hostkey, - session->server_hostkey_len); - libssh2_sha256_final(fingerprint_ctx, - session->server_hostkey_sha256); + if(libssh2_sha256_init(&fingerprint_ctx) && + libssh2_sha256_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len) && + libssh2_sha256_final(fingerprint_ctx, + session->server_hostkey_sha256)) { session->server_hostkey_sha256_valid = TRUE; } else { diff --git a/src/libgcrypt.c b/src/libgcrypt.c index b0f26b51..b92ec7c9 100644 --- a/src/libgcrypt.c +++ b/src/libgcrypt.c @@ -194,7 +194,9 @@ _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa, gcry_sexp_t s_sig, s_hash; int rc = -1; - libssh2_sha1(m, m_len, hash); + if(libssh2_sha1(m, m_len, hash)) { + return -1; + } rc = gcry_sexp_build(&s_hash, NULL, "(data (flags pkcs1) (hash sha1 %b))", @@ -643,7 +645,9 @@ _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx, gcry_sexp_t s_sig, s_hash; int rc = -1; - libssh2_sha1(m, m_len, hash + 1); + if(libssh2_sha1(m, m_len, hash + 1)) { + return -1; + } hash[0] = 0; if(gcry_sexp_build(&s_hash, NULL, "(data(flags raw)(value %b))", diff --git a/src/libgcrypt.h b/src/libgcrypt.h index 09dd91c6..7fc81487 100644 --- a/src/libgcrypt.h +++ b/src/libgcrypt.h @@ -84,63 +84,59 @@ #define libssh2_prepare_iovec(vec, len) /* Empty. */ #define libssh2_sha1_ctx gcry_md_hd_t - /* returns 0 in case of failure */ #define libssh2_sha1_init(ctx) \ (GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA1, 0)) #define libssh2_sha1_update(ctx, data, len) \ - gcry_md_write(ctx, (unsigned char *) data, len) + (gcry_md_write(ctx, (unsigned char *) data, len), 1) #define libssh2_sha1_final(ctx, out) \ - memcpy(out, gcry_md_read(ctx, 0), SHA_DIGEST_LENGTH), gcry_md_close(ctx) + (memcpy(out, gcry_md_read(ctx, 0), SHA_DIGEST_LENGTH), \ + gcry_md_close(ctx), 1) #define libssh2_sha1(message, len, out) \ - gcry_md_hash_buffer(GCRY_MD_SHA1, out, message, len) + (gcry_md_hash_buffer(GCRY_MD_SHA1, out, message, len), 0) #define libssh2_sha256_ctx gcry_md_hd_t - #define libssh2_sha256_init(ctx) \ (GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA256, 0)) #define libssh2_sha256_update(ctx, data, len) \ - gcry_md_write(ctx, (unsigned char *) data, len) + (gcry_md_write(ctx, (unsigned char *) data, len), 1) #define libssh2_sha256_final(ctx, out) \ - memcpy(out, gcry_md_read(ctx, 0), SHA256_DIGEST_LENGTH), gcry_md_close(ctx) + (memcpy(out, gcry_md_read(ctx, 0), SHA256_DIGEST_LENGTH), \ + gcry_md_close(ctx), 1) #define libssh2_sha256(message, len, out) \ - gcry_md_hash_buffer(GCRY_MD_SHA256, out, message, len) + (gcry_md_hash_buffer(GCRY_MD_SHA256, out, message, len), 0) #define libssh2_sha384_ctx gcry_md_hd_t - #define libssh2_sha384_init(ctx) \ (GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA384, 0)) #define libssh2_sha384_update(ctx, data, len) \ - gcry_md_write(ctx, (unsigned char *) data, len) + (gcry_md_write(ctx, (unsigned char *) data, len), 1) #define libssh2_sha384_final(ctx, out) \ - memcpy(out, gcry_md_read(ctx, 0), SHA384_DIGEST_LENGTH), gcry_md_close(ctx) + (memcpy(out, gcry_md_read(ctx, 0), SHA384_DIGEST_LENGTH), \ + gcry_md_close(ctx), 1) #define libssh2_sha384(message, len, out) \ - gcry_md_hash_buffer(GCRY_MD_SHA384, out, message, len) + (gcry_md_hash_buffer(GCRY_MD_SHA384, out, message, len), 0) #define libssh2_sha512_ctx gcry_md_hd_t - #define libssh2_sha512_init(ctx) \ (GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA512, 0)) #define libssh2_sha512_update(ctx, data, len) \ - gcry_md_write(ctx, (unsigned char *) data, len) + (gcry_md_write(ctx, (unsigned char *) data, len), 1) #define libssh2_sha512_final(ctx, out) \ - memcpy(out, gcry_md_read(ctx, 0), SHA512_DIGEST_LENGTH), gcry_md_close(ctx) + (memcpy(out, gcry_md_read(ctx, 0), SHA512_DIGEST_LENGTH), \ + gcry_md_close(ctx), 1) #define libssh2_sha512(message, len, out) \ - gcry_md_hash_buffer(GCRY_MD_SHA512, out, message, len) + (gcry_md_hash_buffer(GCRY_MD_SHA512, out, message, len), 0) #if LIBSSH2_MD5 || LIBSSH2_MD5_PEM #define libssh2_md5_ctx gcry_md_hd_t - -/* returns 0 in case of failure */ #define libssh2_md5_init(ctx) \ (GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_MD5, 0)) - #define libssh2_md5_update(ctx, data, len) \ - gcry_md_write(ctx, (unsigned char *) data, len) + (gcry_md_write(ctx, (unsigned char *) data, len), 1) #define libssh2_md5_final(ctx, out) \ - memcpy(out, gcry_md_read(ctx, 0), MD5_DIGEST_LENGTH), gcry_md_close(ctx) -#define libssh2_md5(message, len, out) \ - gcry_md_hash_buffer(GCRY_MD_MD5, out, message, len) + (memcpy(out, gcry_md_read(ctx, 0), MD5_DIGEST_LENGTH), \ + gcry_md_close(ctx), 1) #endif #define libssh2_hmac_ctx gcry_md_hd_t diff --git a/src/mbedtls.c b/src/mbedtls.c index c7cdae62..158d9b08 100644 --- a/src/mbedtls.c +++ b/src/mbedtls.c @@ -219,7 +219,7 @@ _libssh2_mbedtls_hash_final(mbedtls_md_context_t *ctx, unsigned char *hash) ret = mbedtls_md_finish(ctx, hash); mbedtls_md_free(ctx); - return ret == 0 ? 0 : -1; + return ret == 0 ? 1 : 0; } int diff --git a/src/mbedtls.h b/src/mbedtls.h index 1175c1a9..afe6458a 100644 --- a/src/mbedtls.h +++ b/src/mbedtls.h @@ -158,7 +158,7 @@ #define libssh2_sha1_init(pctx) \ _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA1, NULL, 0) #define libssh2_sha1_update(ctx, data, datalen) \ - mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) + (mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) == 0) #define libssh2_sha1_final(ctx, hash) \ _libssh2_mbedtls_hash_final(&ctx, hash) #define libssh2_sha1(data, datalen, hash) \ @@ -175,7 +175,7 @@ #define libssh2_sha256_init(pctx) \ _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA256, NULL, 0) #define libssh2_sha256_update(ctx, data, datalen) \ - mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) + (mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) == 0) #define libssh2_sha256_final(ctx, hash) \ _libssh2_mbedtls_hash_final(&ctx, hash) #define libssh2_sha256(data, datalen, hash) \ @@ -192,7 +192,7 @@ #define libssh2_sha384_init(pctx) \ _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA384, NULL, 0) #define libssh2_sha384_update(ctx, data, datalen) \ - mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) + (mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) == 0) #define libssh2_sha384_final(ctx, hash) \ _libssh2_mbedtls_hash_final(&ctx, hash) #define libssh2_sha384(data, datalen, hash) \ @@ -209,7 +209,7 @@ #define libssh2_sha512_init(pctx) \ _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA512, NULL, 0) #define libssh2_sha512_update(ctx, data, datalen) \ - mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) + (mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) == 0) #define libssh2_sha512_final(ctx, hash) \ _libssh2_mbedtls_hash_final(&ctx, hash) #define libssh2_sha512(data, datalen, hash) \ @@ -227,11 +227,9 @@ #define libssh2_md5_init(pctx) \ _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_MD5, NULL, 0) #define libssh2_md5_update(ctx, data, datalen) \ - mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) + (mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) == 0) #define libssh2_md5_final(ctx, hash) \ _libssh2_mbedtls_hash_final(&ctx, hash) -#define libssh2_md5(data, datalen, hash) \ - _libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_MD5, hash) #endif /*******************************************************************/ diff --git a/src/openssl.c b/src/openssl.c index 58b8cf7f..60b855da 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -860,20 +860,23 @@ _libssh2_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx ** ec_ctx, #define LIBSSH2_ECDSA_VERIFY(digest_type) \ do { \ unsigned char hash[SHA##digest_type##_DIGEST_LENGTH]; \ - libssh2_sha##digest_type(m, m_len, hash); \ - ret = EVP_PKEY_verify_init(ctx); \ - if(ret > 0) { \ - ret = EVP_PKEY_verify(ctx, der, der_len, hash, \ - SHA##digest_type##_DIGEST_LENGTH); \ + if(libssh2_sha##digest_type(m, m_len, hash) == 0) { \ + ret = EVP_PKEY_verify_init(ctx); \ + if(ret > 0) { \ + ret = EVP_PKEY_verify(ctx, der, der_len, hash, \ + SHA##digest_type##_DIGEST_LENGTH); \ + } \ } \ } while(0) #else #define LIBSSH2_ECDSA_VERIFY(digest_type) \ do { \ unsigned char hash[SHA##digest_type##_DIGEST_LENGTH]; \ - libssh2_sha##digest_type(m, m_len, hash); \ - ret = ECDSA_do_verify(hash, SHA##digest_type##_DIGEST_LENGTH, \ - ecdsa_sig, ec_key); \ + if(libssh2_sha##digest_type(m, m_len, hash) == 0) { \ + ret = ECDSA_do_verify(hash, \ + SHA##digest_type##_DIGEST_LENGTH, \ + ecdsa_sig, ec_key); \ + } \ } while(0) #endif @@ -2993,6 +2996,30 @@ _libssh2_sha1_init(libssh2_sha1_ctx *ctx) #endif } +int +_libssh2_sha1_update(libssh2_sha1_ctx *ctx, + const void *data, size_t len) +{ +#ifdef HAVE_OPAQUE_STRUCTS + return EVP_DigestUpdate(*ctx, data, len); +#else + return EVP_DigestUpdate(ctx, data, len); +#endif +} + +int +_libssh2_sha1_final(libssh2_sha1_ctx *ctx, + unsigned char *out) +{ +#ifdef HAVE_OPAQUE_STRUCTS + int ret = EVP_DigestFinal(*ctx, out, NULL); + EVP_MD_CTX_free(*ctx); + return ret; +#else + return EVP_DigestFinal(ctx, out, NULL); +#endif +} + int _libssh2_sha1(const unsigned char *message, size_t len, unsigned char *out) @@ -3045,6 +3072,30 @@ _libssh2_sha256_init(libssh2_sha256_ctx *ctx) #endif } +int +_libssh2_sha256_update(libssh2_sha256_ctx *ctx, + const void *data, size_t len) +{ +#ifdef HAVE_OPAQUE_STRUCTS + return EVP_DigestUpdate(*ctx, data, len); +#else + return EVP_DigestUpdate(ctx, data, len); +#endif +} + +int +_libssh2_sha256_final(libssh2_sha256_ctx *ctx, + unsigned char *out) +{ +#ifdef HAVE_OPAQUE_STRUCTS + int ret = EVP_DigestFinal(*ctx, out, NULL); + EVP_MD_CTX_free(*ctx); + return ret; +#else + return EVP_DigestFinal(ctx, out, NULL); +#endif +} + int _libssh2_sha256(const unsigned char *message, size_t len, unsigned char *out) @@ -3097,6 +3148,30 @@ _libssh2_sha384_init(libssh2_sha384_ctx *ctx) #endif } +int +_libssh2_sha384_update(libssh2_sha384_ctx *ctx, + const void *data, size_t len) +{ +#ifdef HAVE_OPAQUE_STRUCTS + return EVP_DigestUpdate(*ctx, data, len); +#else + return EVP_DigestUpdate(ctx, data, len); +#endif +} + +int +_libssh2_sha384_final(libssh2_sha384_ctx *ctx, + unsigned char *out) +{ +#ifdef HAVE_OPAQUE_STRUCTS + int ret = EVP_DigestFinal(*ctx, out, NULL); + EVP_MD_CTX_free(*ctx); + return ret; +#else + return EVP_DigestFinal(ctx, out, NULL); +#endif +} + int _libssh2_sha384(const unsigned char *message, size_t len, unsigned char *out) @@ -3149,6 +3224,30 @@ _libssh2_sha512_init(libssh2_sha512_ctx *ctx) #endif } +int +_libssh2_sha512_update(libssh2_sha512_ctx *ctx, + const void *data, size_t len) +{ +#ifdef HAVE_OPAQUE_STRUCTS + return EVP_DigestUpdate(*ctx, data, len); +#else + return EVP_DigestUpdate(ctx, data, len); +#endif +} + +int +_libssh2_sha512_final(libssh2_sha512_ctx *ctx, + unsigned char *out) +{ +#ifdef HAVE_OPAQUE_STRUCTS + int ret = EVP_DigestFinal(*ctx, out, NULL); + EVP_MD_CTX_free(*ctx); + return ret; +#else + return EVP_DigestFinal(ctx, out, NULL); +#endif +} + int _libssh2_sha512(const unsigned char *message, size_t len, unsigned char *out) @@ -3214,6 +3313,30 @@ _libssh2_md5_init(libssh2_md5_ctx *ctx) return EVP_DigestInit(ctx, EVP_get_digestbyname("md5")); #endif } + +int +_libssh2_md5_update(libssh2_md5_ctx *ctx, + const void *data, size_t len) +{ +#ifdef HAVE_OPAQUE_STRUCTS + return EVP_DigestUpdate(*ctx, data, len); +#else + return EVP_DigestUpdate(ctx, data, len); +#endif +} + +int +_libssh2_md5_final(libssh2_md5_ctx *ctx, + unsigned char *out) +{ +#ifdef HAVE_OPAQUE_STRUCTS + int ret = EVP_DigestFinal(*ctx, out, NULL); + EVP_MD_CTX_free(*ctx); + return ret; +#else + return EVP_DigestFinal(ctx, out, NULL); +#endif +} #endif #if LIBSSH2_ECDSA diff --git a/src/openssl.h b/src/openssl.h index a236c1d6..e44c8749 100644 --- a/src/openssl.h +++ b/src/openssl.h @@ -216,19 +216,15 @@ /* returns 0 in case of failure */ int _libssh2_sha1_init(libssh2_sha1_ctx *ctx); -#define libssh2_sha1_init(x) _libssh2_sha1_init(x) -#ifdef HAVE_OPAQUE_STRUCTS -#define libssh2_sha1_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len) -#define libssh2_sha1_final(ctx, out) do { \ - EVP_DigestFinal(ctx, out, NULL); \ - EVP_MD_CTX_free(ctx); \ - } while(0) -#else /* !HAVE_OPAQUE_STRUCTS */ -#define libssh2_sha1_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len) -#define libssh2_sha1_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) -#endif /* HAVE_OPAQUE_STRUCTS */ +int _libssh2_sha1_update(libssh2_sha1_ctx *ctx, + const void *data, size_t len); +int _libssh2_sha1_final(libssh2_sha1_ctx *ctx, unsigned char *out); int _libssh2_sha1(const unsigned char *message, size_t len, unsigned char *out); +#define libssh2_sha1_init(x) _libssh2_sha1_init(x) +#define libssh2_sha1_update(ctx, data, len) \ + _libssh2_sha1_update(&(ctx), data, len) +#define libssh2_sha1_final(ctx, out) _libssh2_sha1_final(&(ctx), out) #define libssh2_sha1(x,y,z) _libssh2_sha1(x,y,z) #ifdef HAVE_OPAQUE_STRUCTS @@ -239,20 +235,15 @@ int _libssh2_sha1(const unsigned char *message, size_t len, /* returns 0 in case of failure */ int _libssh2_sha256_init(libssh2_sha256_ctx *ctx); -#define libssh2_sha256_init(x) _libssh2_sha256_init(x) -#ifdef HAVE_OPAQUE_STRUCTS -#define libssh2_sha256_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len) -#define libssh2_sha256_final(ctx, out) do { \ - EVP_DigestFinal(ctx, out, NULL); \ - EVP_MD_CTX_free(ctx); \ - } while(0) -#else /* !HAVE_OPAQUE_STRUCTS */ -#define libssh2_sha256_update(ctx, data, len) \ - EVP_DigestUpdate(&(ctx), data, len) -#define libssh2_sha256_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) -#endif /* HAVE_OPAQUE_STRUCTS */ +int _libssh2_sha256_update(libssh2_sha256_ctx *ctx, + const void *data, size_t len); +int _libssh2_sha256_final(libssh2_sha256_ctx *ctx, unsigned char *out); int _libssh2_sha256(const unsigned char *message, size_t len, unsigned char *out); +#define libssh2_sha256_init(x) _libssh2_sha256_init(x) +#define libssh2_sha256_update(ctx, data, len) \ + _libssh2_sha256_update(&(ctx), data, len) +#define libssh2_sha256_final(ctx, out) _libssh2_sha256_final(&(ctx), out) #define libssh2_sha256(x,y,z) _libssh2_sha256(x,y,z) #ifdef HAVE_OPAQUE_STRUCTS @@ -263,20 +254,15 @@ int _libssh2_sha256(const unsigned char *message, size_t len, /* returns 0 in case of failure */ int _libssh2_sha384_init(libssh2_sha384_ctx *ctx); -#define libssh2_sha384_init(x) _libssh2_sha384_init(x) -#ifdef HAVE_OPAQUE_STRUCTS -#define libssh2_sha384_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len) -#define libssh2_sha384_final(ctx, out) do { \ - EVP_DigestFinal(ctx, out, NULL); \ - EVP_MD_CTX_free(ctx); \ - } while(0) -#else /* !HAVE_OPAQUE_STRUCTS */ -#define libssh2_sha384_update(ctx, data, len) \ - EVP_DigestUpdate(&(ctx), data, len) -#define libssh2_sha384_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) -#endif /* HAVE_OPAQUE_STRUCTS */ +int _libssh2_sha384_update(libssh2_sha384_ctx *ctx, + const void *data, size_t len); +int _libssh2_sha384_final(libssh2_sha384_ctx *ctx, unsigned char *out); int _libssh2_sha384(const unsigned char *message, size_t len, unsigned char *out); +#define libssh2_sha384_init(x) _libssh2_sha384_init(x) +#define libssh2_sha384_update(ctx, data, len) \ + _libssh2_sha384_update(&(ctx), data, len) +#define libssh2_sha384_final(ctx, out) _libssh2_sha384_final(&(ctx), out) #define libssh2_sha384(x,y,z) _libssh2_sha384(x,y,z) #ifdef HAVE_OPAQUE_STRUCTS @@ -287,20 +273,15 @@ int _libssh2_sha384(const unsigned char *message, size_t len, /* returns 0 in case of failure */ int _libssh2_sha512_init(libssh2_sha512_ctx *ctx); -#define libssh2_sha512_init(x) _libssh2_sha512_init(x) -#ifdef HAVE_OPAQUE_STRUCTS -#define libssh2_sha512_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len) -#define libssh2_sha512_final(ctx, out) do { \ - EVP_DigestFinal(ctx, out, NULL); \ - EVP_MD_CTX_free(ctx); \ - } while(0) -#else /* !HAVE_OPAQUE_STRUCTS */ -#define libssh2_sha512_update(ctx, data, len) \ - EVP_DigestUpdate(&(ctx), data, len) -#define libssh2_sha512_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) -#endif /* HAVE_OPAQUE_STRUCTS */ +int _libssh2_sha512_update(libssh2_sha512_ctx *ctx, + const void *data, size_t len); +int _libssh2_sha512_final(libssh2_sha512_ctx *ctx, unsigned char *out); int _libssh2_sha512(const unsigned char *message, size_t len, unsigned char *out); +#define libssh2_sha512_init(x) _libssh2_sha512_init(x) +#define libssh2_sha512_update(ctx, data, len) \ + _libssh2_sha512_update(&(ctx), data, len) +#define libssh2_sha512_final(ctx, out) _libssh2_sha512_final(&(ctx), out) #define libssh2_sha512(x,y,z) _libssh2_sha512(x,y,z) #if LIBSSH2_MD5 || LIBSSH2_MD5_PEM @@ -312,17 +293,13 @@ int _libssh2_sha512(const unsigned char *message, size_t len, /* returns 0 in case of failure */ int _libssh2_md5_init(libssh2_md5_ctx *ctx); +int _libssh2_md5_update(libssh2_md5_ctx *ctx, + const void *data, size_t len); +int _libssh2_md5_final(libssh2_md5_ctx *ctx, unsigned char *out); #define libssh2_md5_init(x) _libssh2_md5_init(x) -#ifdef HAVE_OPAQUE_STRUCTS -#define libssh2_md5_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len) -#define libssh2_md5_final(ctx, out) do { \ - EVP_DigestFinal(ctx, out, NULL); \ - EVP_MD_CTX_free(ctx); \ - } while(0) -#else /* !HAVE_OPAQUE_STRUCTS */ -#define libssh2_md5_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len) -#define libssh2_md5_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) -#endif /* HAVE_OPAQUE_STRUCTS */ +#define libssh2_md5_update(ctx, data, len) \ + _libssh2_md5_update(&(ctx), data, len) +#define libssh2_md5_final(ctx, out) _libssh2_md5_final(&(ctx), out) #endif /* LIBSSH2_MD5 || LIBSSH2_MD5_PEM */ #ifdef USE_OPENSSL_3 diff --git a/src/os400qc3.c b/src/os400qc3.c index 44fe60c5..ae5693fc 100644 --- a/src/os400qc3.c +++ b/src/os400qc3.c @@ -949,7 +949,7 @@ _libssh2_os400qc3_crypto_dtor(_libssh2_os400qc3_crypto_ctx *x) *******************************************************************/ int -libssh2_os400qc3_hash_init(Qc3_Format_ALGD0100_T *x, unsigned int algorithm) +_libssh2_os400qc3_hash_init(Qc3_Format_ALGD0100_T *x, unsigned int algorithm) { Qc3_Format_ALGD0500_T algd; Qus_EC_t errcode; @@ -966,40 +966,46 @@ libssh2_os400qc3_hash_init(Qc3_Format_ALGD0100_T *x, unsigned int algorithm) return errcode.Bytes_Available? 0: 1; } -void -libssh2_os400qc3_hash_update(Qc3_Format_ALGD0100_T *ctx, - const unsigned char *data, int len) +int +_libssh2_os400qc3_hash_update(Qc3_Format_ALGD0100_T *ctx, + const unsigned char *data, int len) { char dummy[64]; + Qus_EC_t errcode; ctx->Final_Op_Flag = Qc3_Continue; + set_EC_length(errcode, sizeof(errcode)); Qc3CalculateHash((char *) data, &len, Qc3_Data, (char *) ctx, - Qc3_Alg_Token, anycsp, NULL, dummy, (char *) &ecnull); -} - -void -libssh2_os400qc3_hash_final(Qc3_Format_ALGD0100_T *ctx, unsigned char *out) -{ - char data; - - ctx->Final_Op_Flag = Qc3_Final; - Qc3CalculateHash(&data, &zero, Qc3_Data, (char *) ctx, Qc3_Alg_Token, - anycsp, NULL, (char *) out, (char *) &ecnull); - Qc3DestroyAlgorithmContext(ctx->Alg_Context_Token, (char *) &ecnull); - memset(ctx->Alg_Context_Token, 0, sizeof(ctx->Alg_Context_Token)); + Qc3_Alg_Token, anycsp, NULL, dummy, &errcode); + return errcode.Bytes_Available? 0: 1; } int -libssh2_os400qc3_hash(const unsigned char *message, unsigned long len, - unsigned char *out, unsigned int algo) +_libssh2_os400qc3_hash_final(Qc3_Format_ALGD0100_T *ctx, unsigned char *out) +{ + char data; + Qus_EC_t errcode; + + ctx->Final_Op_Flag = Qc3_Final; + set_EC_length(errcode, sizeof(errcode)); + Qc3CalculateHash(&data, &zero, Qc3_Data, (char *) ctx, Qc3_Alg_Token, + anycsp, NULL, (char *) out, &errcode); + Qc3DestroyAlgorithmContext(ctx->Alg_Context_Token, (char *) &ecnull); + memset(ctx->Alg_Context_Token, 0, sizeof(ctx->Alg_Context_Token)); + return errcode.Bytes_Available? 0: 1; +} + +int +_libssh2_os400qc3_hash(const unsigned char *message, unsigned long len, + unsigned char *out, unsigned int algo) { Qc3_Format_ALGD0100_T ctx; - if(!libssh2_os400qc3_hash_init(&ctx, algo)) + if(!_libssh2_os400qc3_hash_init(&ctx, algo) || + !_libssh2_os400qc3_hash_update(&ctx, message, len) || + !_libssh2_os400qc3_hash_final(&ctx, out)) return 1; - libssh2_os400qc3_hash_update(&ctx, message, len); - libssh2_os400qc3_hash_final(&ctx, out); return 0; } @@ -1020,7 +1026,7 @@ libssh2_os400qc3_hmac_init(_libssh2_os400qc3_crypto_ctx *ctx, key = (void *) lkey; keylen = minkeylen; } - if(!libssh2_os400qc3_hash_init(&ctx->hash, algo)) + if(!_libssh2_os400qc3_hash_init(&ctx->hash, algo)) return 0; set_EC_length(errcode, sizeof(errcode)); Qc3CreateKeyContext((char *) key, &keylen, binstring, &algo, qc3clear, @@ -1432,15 +1438,19 @@ pbkdf1(LIBSSH2_SESSION *session, char **dk, const unsigned char *passphrase, return -1; /* Initial hash. */ - libssh2_os400qc3_hash_init(&hctx, pkcs5->hash); - libssh2_os400qc3_hash_update(&hctx, passphrase, strlen(passphrase)); + /* FIXME: check result */ + _libssh2_os400qc3_hash_init(&hctx, pkcs5->hash); + /* FIXME: check result */ + _libssh2_os400qc3_hash_update(&hctx, passphrase, strlen(passphrase)); hctx.Final_Op_Flag = Qc3_Final; + /* FIXME: check result */ Qc3CalculateHash((char *) pkcs5->salt, &len, Qc3_Data, (char *) &hctx, Qc3_Alg_Token, anycsp, NULL, *dk, (char *) &ecnull); /* Iterate. */ len = pkcs5->hashlen; for(i = 1; i < pkcs5->itercount; i++) + /* FIXME: check result */ Qc3CalculateHash((char *) *dk, &len, Qc3_Data, (char *) &hctx, Qc3_Alg_Token, anycsp, NULL, *dk, (char *) &ecnull); diff --git a/src/os400qc3.h b/src/os400qc3.h index c9328ff6..e1e4b117 100644 --- a/src/os400qc3.h +++ b/src/os400qc3.h @@ -251,40 +251,40 @@ typedef struct { /* Diffie-Hellman context. */ #define libssh2_hmac_ctx _libssh2_os400qc3_crypto_ctx #define _libssh2_cipher_ctx _libssh2_os400qc3_crypto_ctx -#define libssh2_sha1_init(x) libssh2_os400qc3_hash_init(x, Qc3_SHA1) +#define libssh2_sha1_init(x) _libssh2_os400qc3_hash_init(x, Qc3_SHA1) #define libssh2_sha1_update(ctx, data, len) \ - libssh2_os400qc3_hash_update(&(ctx), data, len) + _libssh2_os400qc3_hash_update(&(ctx), data, len) #define libssh2_sha1_final(ctx, out) \ - libssh2_os400qc3_hash_final(&(ctx), out) -#define libssh2_sha256_init(x) libssh2_os400qc3_hash_init(x, Qc3_SHA256) + _libssh2_os400qc3_hash_final(&(ctx), out) +#define libssh2_sha256_init(x) _libssh2_os400qc3_hash_init(x, Qc3_SHA256) #define libssh2_sha256_update(ctx, data, len) \ - libssh2_os400qc3_hash_update(&(ctx), data, len) + _libssh2_os400qc3_hash_update(&(ctx), data, len) #define libssh2_sha256_final(ctx, out) \ - libssh2_os400qc3_hash_final(&(ctx), out) + _libssh2_os400qc3_hash_final(&(ctx), out) #define libssh2_sha256(message, len, out) \ - libssh2_os400qc3_hash(message, len, out, \ - Qc3_SHA256) -#define libssh2_sha384_init(x) libssh2_os400qc3_hash_init(x, Qc3_SHA384) + _libssh2_os400qc3_hash(message, len, out, \ + Qc3_SHA256) +#define libssh2_sha384_init(x) _libssh2_os400qc3_hash_init(x, Qc3_SHA384) #define libssh2_sha384_update(ctx, data, len) \ - libssh2_os400qc3_hash_update(&(ctx), data, len) + _libssh2_os400qc3_hash_update(&(ctx), data, len) #define libssh2_sha384_final(ctx, out) \ - libssh2_os400qc3_hash_final(&(ctx), out) + _libssh2_os400qc3_hash_final(&(ctx), out) #define libssh2_sha384(message, len, out) \ - libssh2_os400qc3_hash(message, len, out, \ - Qc3_SHA384) -#define libssh2_sha512_init(x) libssh2_os400qc3_hash_init(x, Qc3_SHA512) + _libssh2_os400qc3_hash(message, len, out, \ + Qc3_SHA384) +#define libssh2_sha512_init(x) _libssh2_os400qc3_hash_init(x, Qc3_SHA512) #define libssh2_sha512_update(ctx, data, len) \ - libssh2_os400qc3_hash_update(&(ctx), data, len) + _libssh2_os400qc3_hash_update(&(ctx), data, len) #define libssh2_sha512_final(ctx, out) \ - libssh2_os400qc3_hash_final(&(ctx), out) + _libssh2_os400qc3_hash_final(&(ctx), out) #define libssh2_sha512(message, len, out) \ - libssh2_os400qc3_hash(message, len, out, \ - Qc3_SHA512) -#define libssh2_md5_init(x) libssh2_os400qc3_hash_init(x, Qc3_MD5) + _libssh2_os400qc3_hash(message, len, out, \ + Qc3_SHA512) +#define libssh2_md5_init(x) _libssh2_os400qc3_hash_init(x, Qc3_MD5) #define libssh2_md5_update(ctx, data, len) \ - libssh2_os400qc3_hash_update(&(ctx), data, len) + _libssh2_os400qc3_hash_update(&(ctx), data, len) #define libssh2_md5_final(ctx, out) \ - libssh2_os400qc3_hash_final(&(ctx), out) + _libssh2_os400qc3_hash_final(&(ctx), out) #define _libssh2_bn_ctx int /* Not used. */ @@ -360,16 +360,16 @@ extern int _libssh2_bn_set_word(_libssh2_bn *bn, unsigned long val); extern int _libssh2_bn_to_bin(_libssh2_bn *bn, unsigned char *val); extern int _libssh2_random(unsigned char *buf, size_t len); extern void _libssh2_os400qc3_crypto_dtor(_libssh2_os400qc3_crypto_ctx *x); -extern int libssh2_os400qc3_hash_init(Qc3_Format_ALGD0100_T *x, - unsigned int algo); -extern void libssh2_os400qc3_hash_update(Qc3_Format_ALGD0100_T *ctx, - const unsigned char *data, - int len); -extern void libssh2_os400qc3_hash_final(Qc3_Format_ALGD0100_T *ctx, - unsigned char *out); -extern int libssh2_os400qc3_hash(const unsigned char *message, - unsigned long len, unsigned char *out, - unsigned int algo); +extern int _libssh2_os400qc3_hash_init(Qc3_Format_ALGD0100_T *x, + unsigned int algo); +extern int _libssh2_os400qc3_hash_update(Qc3_Format_ALGD0100_T *ctx, + const unsigned char *data, + int len); +extern int _libssh2_os400qc3_hash_final(Qc3_Format_ALGD0100_T *ctx, + unsigned char *out); +extern int _libssh2_os400qc3_hash(const unsigned char *message, + unsigned long len, unsigned char *out, + unsigned int algo); extern int _libssh2_os400qc3_rsa_signv(LIBSSH2_SESSION *session, int algo, unsigned char **signature, size_t *signature_len, diff --git a/src/pem.c b/src/pem.c index 41ebf439..c6588968 100644 --- a/src/pem.c +++ b/src/pem.c @@ -218,24 +218,26 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session, libssh2_md5_ctx fingerprint_ctx; /* Perform key derivation (PBKDF1/MD5) */ - if(!libssh2_md5_init(&fingerprint_ctx)) { + if(!libssh2_md5_init(&fingerprint_ctx) || + !libssh2_md5_update(fingerprint_ctx, passphrase, + strlen((char *)passphrase)) || + !libssh2_md5_update(fingerprint_ctx, iv, 8) || + !libssh2_md5_final(fingerprint_ctx, secret)) { ret = -1; goto out; } - libssh2_md5_update(fingerprint_ctx, passphrase, - strlen((char *)passphrase)); - libssh2_md5_update(fingerprint_ctx, iv, 8); - libssh2_md5_final(fingerprint_ctx, secret); if(method->secret_len > MD5_DIGEST_LENGTH) { - if(!libssh2_md5_init(&fingerprint_ctx)) { + if(!libssh2_md5_init(&fingerprint_ctx) || + !libssh2_md5_update(fingerprint_ctx, + secret, MD5_DIGEST_LENGTH) || + !libssh2_md5_update(fingerprint_ctx, + passphrase, strlen((char *)passphrase)) || + !libssh2_md5_update(fingerprint_ctx, iv, 8) || + !libssh2_md5_final(fingerprint_ctx, + secret + MD5_DIGEST_LENGTH)) { ret = -1; goto out; } - libssh2_md5_update(fingerprint_ctx, secret, MD5_DIGEST_LENGTH); - libssh2_md5_update(fingerprint_ctx, passphrase, - strlen((char *)passphrase)); - libssh2_md5_update(fingerprint_ctx, iv, 8); - libssh2_md5_final(fingerprint_ctx, secret + MD5_DIGEST_LENGTH); } /* Initialize the decryption */ diff --git a/src/wincng.h b/src/wincng.h index 68407e31..190cb108 100644 --- a/src/wincng.h +++ b/src/wincng.h @@ -158,9 +158,9 @@ typedef struct __libssh2_wincng_hash_ctx { (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA1, \ SHA_DIGEST_LENGTH, NULL, 0) == 0) #define libssh2_sha1_update(ctx, data, datalen) \ - _libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) + (_libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) == 0) #define libssh2_sha1_final(ctx, hash) \ - _libssh2_wincng_hash_final(&ctx, hash) + (_libssh2_wincng_hash_final(&ctx, hash) == 0) #define libssh2_sha1(data, datalen, hash) \ _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA1, \ hash, SHA_DIGEST_LENGTH) @@ -170,9 +170,9 @@ typedef struct __libssh2_wincng_hash_ctx { (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA256, \ SHA256_DIGEST_LENGTH, NULL, 0) == 0) #define libssh2_sha256_update(ctx, data, datalen) \ - _libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) + (_libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) == 0) #define libssh2_sha256_final(ctx, hash) \ - _libssh2_wincng_hash_final(&ctx, hash) + (_libssh2_wincng_hash_final(&ctx, hash) == 0) #define libssh2_sha256(data, datalen, hash) \ _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA256, \ hash, SHA256_DIGEST_LENGTH) @@ -182,9 +182,9 @@ typedef struct __libssh2_wincng_hash_ctx { (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA384, \ SHA384_DIGEST_LENGTH, NULL, 0) == 0) #define libssh2_sha384_update(ctx, data, datalen) \ - _libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) + (_libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) == 0) #define libssh2_sha384_final(ctx, hash) \ - _libssh2_wincng_hash_final(&ctx, hash) + (_libssh2_wincng_hash_final(&ctx, hash) == 0) #define libssh2_sha384(data, datalen, hash) \ _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA384, \ hash, SHA384_DIGEST_LENGTH) @@ -194,9 +194,9 @@ typedef struct __libssh2_wincng_hash_ctx { (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA512, \ SHA512_DIGEST_LENGTH, NULL, 0) == 0) #define libssh2_sha512_update(ctx, data, datalen) \ - _libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) + (_libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) == 0) #define libssh2_sha512_final(ctx, hash) \ - _libssh2_wincng_hash_final(&ctx, hash) + (_libssh2_wincng_hash_final(&ctx, hash) == 0) #define libssh2_sha512(data, datalen, hash) \ _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA512, \ hash, SHA512_DIGEST_LENGTH) @@ -207,12 +207,9 @@ typedef struct __libssh2_wincng_hash_ctx { (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashMD5, \ MD5_DIGEST_LENGTH, NULL, 0) == 0) #define libssh2_md5_update(ctx, data, datalen) \ - _libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) + (_libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) == 0) #define libssh2_md5_final(ctx, hash) \ - _libssh2_wincng_hash_final(&ctx, hash) -#define libssh2_md5(data, datalen, hash) \ - _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashMD5, \ - hash, MD5_DIGEST_LENGTH) + (_libssh2_wincng_hash_final(&ctx, hash) == 0) #endif /*