diff --git a/include/libssh/wrapper.h b/include/libssh/wrapper.h index 07e64018..b3e28eac 100644 --- a/include/libssh/wrapper.h +++ b/include/libssh/wrapper.h @@ -72,29 +72,33 @@ struct ssh_crypto_struct; typedef struct ssh_mac_ctx_struct *ssh_mac_ctx; MD5CTX md5_init(void); -void md5_update(MD5CTX c, const void *data, size_t len); -void md5_final(unsigned char *md,MD5CTX c); +void md5_ctx_free(MD5CTX); +int md5_update(MD5CTX c, const void *data, size_t len); +int md5_final(unsigned char *md, MD5CTX c); SHACTX sha1_init(void); -void sha1_update(SHACTX c, const void *data, size_t len); -void sha1_final(unsigned char *md,SHACTX c); -void sha1(const unsigned char *digest,size_t len,unsigned char *hash); +void sha1_ctx_free(SHACTX); +int sha1_update(SHACTX c, const void *data, size_t len); +int sha1_final(unsigned char *md,SHACTX c); +int sha1(const unsigned char *digest,size_t len, unsigned char *hash); SHA256CTX sha256_init(void); -void sha256_update(SHA256CTX c, const void *data, size_t len); -void sha256_final(unsigned char *md,SHA256CTX c); -void sha256(const unsigned char *digest, size_t len, unsigned char *hash); +void sha256_ctx_free(SHA256CTX); +int sha256_update(SHA256CTX c, const void *data, size_t len); +int sha256_final(unsigned char *md,SHA256CTX c); +int sha256(const unsigned char *digest, size_t len, unsigned char *hash); SHA384CTX sha384_init(void); -void sha384_update(SHA384CTX c, const void *data, size_t len); -void sha384_final(unsigned char *md,SHA384CTX c); -void sha384(const unsigned char *digest, size_t len, unsigned char *hash); +void sha384_ctx_free(SHA384CTX); +int sha384_update(SHA384CTX c, const void *data, size_t len); +int sha384_final(unsigned char *md,SHA384CTX c); +int sha384(const unsigned char *digest, size_t len, unsigned char *hash); SHA512CTX sha512_init(void); -void sha512_update(SHA512CTX c, const void *data, size_t len); -void sha512_final(unsigned char *md,SHA512CTX c); -void sha512(const unsigned char *digest, size_t len, unsigned char *hash); - +void sha512_ctx_free(SHA512CTX); +int sha512_update(SHA512CTX c, const void *data, size_t len); +int sha512_final(unsigned char *md,SHA512CTX c); +int sha512(const unsigned char *digest, size_t len, unsigned char *hash); HMACCTX hmac_init(const void *key,size_t len, enum ssh_hmac_e type); int hmac_update(HMACCTX c, const void *data, size_t len); diff --git a/src/kdf.c b/src/kdf.c index 987ae972..a8e534e5 100644 --- a/src/kdf.c +++ b/src/kdf.c @@ -77,43 +77,66 @@ static ssh_mac_ctx ssh_mac_ctx_init(enum ssh_kdf_digest type) } } -static void ssh_mac_update(ssh_mac_ctx ctx, const void *data, size_t len) +static void ssh_mac_ctx_free(ssh_mac_ctx ctx) { - switch (ctx->digest_type) { - case SSH_KDF_SHA1: - sha1_update(ctx->ctx.sha1_ctx, data, len); - break; - case SSH_KDF_SHA256: - sha256_update(ctx->ctx.sha256_ctx, data, len); - break; - case SSH_KDF_SHA384: - sha384_update(ctx->ctx.sha384_ctx, data, len); - break; - case SSH_KDF_SHA512: - sha512_update(ctx->ctx.sha512_ctx, data, len); - break; + if (ctx == NULL) { + return; } -} -static void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx) -{ switch (ctx->digest_type) { case SSH_KDF_SHA1: - sha1_final(md, ctx->ctx.sha1_ctx); + sha1_ctx_free(ctx->ctx.sha1_ctx); break; case SSH_KDF_SHA256: - sha256_final(md, ctx->ctx.sha256_ctx); + sha256_ctx_free(ctx->ctx.sha256_ctx); break; case SSH_KDF_SHA384: - sha384_final(md, ctx->ctx.sha384_ctx); + sha384_ctx_free(ctx->ctx.sha384_ctx); break; case SSH_KDF_SHA512: - sha512_final(md, ctx->ctx.sha512_ctx); + sha512_ctx_free(ctx->ctx.sha512_ctx); break; } SAFE_FREE(ctx); } +static int ssh_mac_update(ssh_mac_ctx ctx, const void *data, size_t len) +{ + switch (ctx->digest_type) { + case SSH_KDF_SHA1: + return sha1_update(ctx->ctx.sha1_ctx, data, len); + case SSH_KDF_SHA256: + return sha256_update(ctx->ctx.sha256_ctx, data, len); + case SSH_KDF_SHA384: + return sha384_update(ctx->ctx.sha384_ctx, data, len); + case SSH_KDF_SHA512: + return sha512_update(ctx->ctx.sha512_ctx, data, len); + } + return SSH_ERROR; +} + +static int ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx) +{ + int rc = SSH_ERROR; + + switch (ctx->digest_type) { + case SSH_KDF_SHA1: + rc = sha1_final(md, ctx->ctx.sha1_ctx); + break; + case SSH_KDF_SHA256: + rc = sha256_final(md, ctx->ctx.sha256_ctx); + break; + case SSH_KDF_SHA384: + rc = sha384_final(md, ctx->ctx.sha384_ctx); + break; + case SSH_KDF_SHA512: + rc = sha512_final(md, ctx->ctx.sha512_ctx); + break; + } + SAFE_FREE(ctx); + return rc; +} + int sshkdf_derive_key(struct ssh_crypto_struct *crypto, unsigned char *key, size_t key_len, @@ -126,6 +149,7 @@ int sshkdf_derive_key(struct ssh_crypto_struct *crypto, unsigned char digest[DIGEST_MAX_LEN]; size_t output_len = crypto->digest_len; ssh_mac_ctx ctx; + int rc; if (DIGEST_MAX_LEN < crypto->digest_len) { return -1; @@ -136,11 +160,30 @@ int sshkdf_derive_key(struct ssh_crypto_struct *crypto, return -1; } - ssh_mac_update(ctx, key, key_len); - ssh_mac_update(ctx, crypto->secret_hash, crypto->digest_len); - ssh_mac_update(ctx, &key_type, 1); - ssh_mac_update(ctx, crypto->session_id, crypto->session_id_len); - ssh_mac_final(digest, ctx); + rc = ssh_mac_update(ctx, key, key_len); + if (rc != SSH_OK) { + ssh_mac_ctx_free(ctx); + return -1; + } + rc = ssh_mac_update(ctx, crypto->secret_hash, crypto->digest_len); + if (rc != SSH_OK) { + ssh_mac_ctx_free(ctx); + return -1; + } + rc = ssh_mac_update(ctx, &key_type, 1); + if (rc != SSH_OK) { + ssh_mac_ctx_free(ctx); + return -1; + } + rc = ssh_mac_update(ctx, crypto->session_id, crypto->session_id_len); + if (rc != SSH_OK) { + ssh_mac_ctx_free(ctx); + return -1; + } + rc = ssh_mac_final(digest, ctx); + if (rc != SSH_OK) { + return -1; + } if (requested_len < output_len) { output_len = requested_len; @@ -152,10 +195,25 @@ int sshkdf_derive_key(struct ssh_crypto_struct *crypto, if (ctx == NULL) { return -1; } - ssh_mac_update(ctx, key, key_len); - ssh_mac_update(ctx, crypto->secret_hash, crypto->digest_len); - ssh_mac_update(ctx, output, output_len); - ssh_mac_final(digest, ctx); + rc = ssh_mac_update(ctx, key, key_len); + if (rc != SSH_OK) { + ssh_mac_ctx_free(ctx); + return -1; + } + rc = ssh_mac_update(ctx, crypto->secret_hash, crypto->digest_len); + if (rc != SSH_OK) { + ssh_mac_ctx_free(ctx); + return -1; + } + rc = ssh_mac_update(ctx, output, output_len); + if (rc != SSH_OK) { + ssh_mac_ctx_free(ctx); + return -1; + } + rc = ssh_mac_final(digest, ctx); + if (rc != SSH_OK) { + return -1; + } if (requested_len < output_len + crypto->digest_len) { memcpy(output + output_len, digest, requested_len - output_len); } else { diff --git a/src/md_crypto.c b/src/md_crypto.c index f5104f04..f7cda8dd 100644 --- a/src/md_crypto.c +++ b/src/md_crypto.c @@ -25,6 +25,7 @@ #include "libssh/crypto.h" #include "libssh/wrapper.h" +#include #include #include #include @@ -46,28 +47,49 @@ sha1_init(void) } void -sha1_update(SHACTX c, const void *data, size_t len) +sha1_ctx_free(SHACTX c) { - EVP_DigestUpdate(c, data, len); -} - -void -sha1_final(unsigned char *md, SHACTX c) -{ - unsigned int mdlen = 0; - - EVP_DigestFinal(c, md, &mdlen); EVP_MD_CTX_free(c); } -void +int +sha1_update(SHACTX c, const void *data, size_t len) +{ + int rc = EVP_DigestUpdate(c, data, len); + if (rc != 1) { + return SSH_ERROR; + } + return SSH_OK; +} + +int +sha1_final(unsigned char *md, SHACTX c) +{ + unsigned int mdlen = 0; + int rc = EVP_DigestFinal(c, md, &mdlen); + + EVP_MD_CTX_free(c); + if (rc != 1) { + return SSH_ERROR; + } + return SSH_OK; +} + +int sha1(const unsigned char *digest, size_t len, unsigned char *hash) { SHACTX c = sha1_init(); - if (c != NULL) { - sha1_update(c, digest, len); - sha1_final(hash, c); + int rc; + + if (c == NULL) { + return SSH_ERROR; } + rc = sha1_update(c, digest, len); + if (rc != SSH_OK) { + EVP_MD_CTX_free(c); + return SSH_ERROR; + } + return sha1_final(hash, c); } SHA256CTX @@ -87,28 +109,49 @@ sha256_init(void) } void -sha256_update(SHA256CTX c, const void *data, size_t len) +sha256_ctx_free(SHA256CTX c) { - EVP_DigestUpdate(c, data, len); -} - -void -sha256_final(unsigned char *md, SHA256CTX c) -{ - unsigned int mdlen = 0; - - EVP_DigestFinal(c, md, &mdlen); EVP_MD_CTX_free(c); } -void +int +sha256_update(SHA256CTX c, const void *data, size_t len) +{ + int rc = EVP_DigestUpdate(c, data, len); + if (rc != 1) { + return SSH_ERROR; + } + return SSH_OK; +} + +int +sha256_final(unsigned char *md, SHA256CTX c) +{ + unsigned int mdlen = 0; + int rc = EVP_DigestFinal(c, md, &mdlen); + + EVP_MD_CTX_free(c); + if (rc != 1) { + return SSH_ERROR; + } + return SSH_OK; +} + +int sha256(const unsigned char *digest, size_t len, unsigned char *hash) { SHA256CTX c = sha256_init(); - if (c != NULL) { - sha256_update(c, digest, len); - sha256_final(hash, c); + int rc; + + if (c == NULL) { + return SSH_ERROR; } + rc = sha256_update(c, digest, len); + if (rc != SSH_OK) { + EVP_MD_CTX_free(c); + return SSH_ERROR; + } + return sha256_final(hash, c); } SHA384CTX @@ -128,28 +171,49 @@ sha384_init(void) } void -sha384_update(SHA384CTX c, const void *data, size_t len) +sha384_ctx_free(SHA384CTX c) { - EVP_DigestUpdate(c, data, len); -} - -void -sha384_final(unsigned char *md, SHA384CTX c) -{ - unsigned int mdlen = 0; - - EVP_DigestFinal(c, md, &mdlen); EVP_MD_CTX_free(c); } -void +int +sha384_update(SHA384CTX c, const void *data, size_t len) +{ + int rc = EVP_DigestUpdate(c, data, len); + if (rc != 1) { + return SSH_ERROR; + } + return SSH_OK; +} + +int +sha384_final(unsigned char *md, SHA384CTX c) +{ + unsigned int mdlen = 0; + int rc = EVP_DigestFinal(c, md, &mdlen); + + EVP_MD_CTX_free(c); + if (rc != 1) { + return SSH_ERROR; + } + return SSH_OK; +} + +int sha384(const unsigned char *digest, size_t len, unsigned char *hash) { SHA384CTX c = sha384_init(); - if (c != NULL) { - sha384_update(c, digest, len); - sha384_final(hash, c); + int rc; + + if (c == NULL) { + return SSH_ERROR; } + rc = sha384_update(c, digest, len); + if (rc != SSH_OK) { + EVP_MD_CTX_free(c); + return SSH_ERROR; + } + return sha384_final(hash, c); } SHA512CTX @@ -169,28 +233,49 @@ sha512_init(void) } void -sha512_update(SHA512CTX c, const void *data, size_t len) +sha512_ctx_free(SHA512CTX c) { - EVP_DigestUpdate(c, data, len); -} - -void -sha512_final(unsigned char *md, SHA512CTX c) -{ - unsigned int mdlen = 0; - - EVP_DigestFinal(c, md, &mdlen); EVP_MD_CTX_free(c); } -void +int +sha512_update(SHA512CTX c, const void *data, size_t len) +{ + int rc = EVP_DigestUpdate(c, data, len); + if (rc != 1) { + return SSH_ERROR; + } + return SSH_OK; +} + +int +sha512_final(unsigned char *md, SHA512CTX c) +{ + unsigned int mdlen = 0; + int rc = EVP_DigestFinal(c, md, &mdlen); + + EVP_MD_CTX_free(c); + if (rc != 1) { + return SSH_ERROR; + } + return SSH_OK; +} + +int sha512(const unsigned char *digest, size_t len, unsigned char *hash) { SHA512CTX c = sha512_init(); - if (c != NULL) { - sha512_update(c, digest, len); - sha512_final(hash, c); + int rc; + + if (c == NULL) { + return SSH_ERROR; } + rc = sha512_update(c, digest, len); + if (rc != SSH_OK) { + EVP_MD_CTX_free(c); + return SSH_ERROR; + } + return sha512_final(hash, c); } MD5CTX @@ -210,16 +295,30 @@ md5_init(void) } void -md5_update(MD5CTX c, const void *data, size_t len) +md5_ctx_free(MD5CTX c) { - EVP_DigestUpdate(c, data, len); + EVP_MD_CTX_free(c); } -void +int +md5_update(MD5CTX c, const void *data, size_t len) +{ + int rc = EVP_DigestUpdate(c, data, len); + if (rc != 1) { + return SSH_ERROR; + } + return SSH_OK; +} + +int md5_final(unsigned char *md, MD5CTX c) { unsigned int mdlen = 0; + int rc = EVP_DigestFinal(c, md, &mdlen); - EVP_DigestFinal(c, md, &mdlen); EVP_MD_CTX_free(c); + if (rc != 1) { + return SSH_ERROR; + } + return SSH_OK; } diff --git a/src/md_gcrypt.c b/src/md_gcrypt.c index 1f0a71f3..93c7b0d9 100644 --- a/src/md_gcrypt.c +++ b/src/md_gcrypt.c @@ -36,24 +36,40 @@ sha1_init(void) return ctx; } -void +int sha1_update(SHACTX c, const void *data, size_t len) { gcry_md_write(c, data, len); + return SSH_OK; } void -sha1_final(unsigned char *md, SHACTX c) +sha1_ctx_free(SHACTX c) { - gcry_md_final(c); - memcpy(md, gcry_md_read(c, 0), SHA_DIGEST_LEN); gcry_md_close(c); } -void +int +sha1_final(unsigned char *md, SHACTX c) +{ + unsigned char *tmp = NULL; + + gcry_md_final(c); + tmp = gcry_md_read(c, 0); + if (tmp == NULL) { + gcry_md_close(c); + return SSH_ERROR; + } + memcpy(md, tmp, SHA_DIGEST_LEN); + gcry_md_close(c); + return SSH_OK; +} + +int sha1(const unsigned char *digest, size_t len, unsigned char *hash) { gcry_md_hash_buffer(GCRY_MD_SHA1, hash, digest, len); + return SSH_OK; } SHA256CTX @@ -66,23 +82,39 @@ sha256_init(void) } void -sha256_update(SHACTX c, const void *data, size_t len) +sha256_ctx_free(SHA256CTX c) { - gcry_md_write(c, data, len); -} - -void -sha256_final(unsigned char *md, SHACTX c) -{ - gcry_md_final(c); - memcpy(md, gcry_md_read(c, 0), SHA256_DIGEST_LEN); gcry_md_close(c); } -void +int +sha256_update(SHACTX c, const void *data, size_t len) +{ + gcry_md_write(c, data, len); + return SSH_OK; +} + +int +sha256_final(unsigned char *md, SHACTX c) +{ + unsigned char *tmp = NULL; + + gcry_md_final(c); + tmp = gcry_md_read(c, 0); + if (tmp == NULL) { + gcry_md_close(c); + return SSH_ERROR; + } + memcpy(md, tmp, SHA256_DIGEST_LEN); + gcry_md_close(c); + return SSH_OK; +} + +int sha256(const unsigned char *digest, size_t len, unsigned char *hash) { gcry_md_hash_buffer(GCRY_MD_SHA256, hash, digest, len); + return SSH_OK; } SHA384CTX @@ -95,23 +127,39 @@ sha384_init(void) } void -sha384_update(SHACTX c, const void *data, size_t len) +sha384_ctx_free(SHA384CTX c) { - gcry_md_write(c, data, len); -} - -void -sha384_final(unsigned char *md, SHACTX c) -{ - gcry_md_final(c); - memcpy(md, gcry_md_read(c, 0), SHA384_DIGEST_LEN); gcry_md_close(c); } -void +int +sha384_update(SHACTX c, const void *data, size_t len) +{ + gcry_md_write(c, data, len); + return SSH_OK; +} + +int +sha384_final(unsigned char *md, SHACTX c) +{ + unsigned char *tmp = NULL; + + gcry_md_final(c); + tmp = gcry_md_read(c, 0); + if (tmp == NULL) { + gcry_md_close(c); + return SSH_ERROR; + } + memcpy(md, tmp, SHA384_DIGEST_LEN); + gcry_md_close(c); + return SSH_OK; +} + +int sha384(const unsigned char *digest, size_t len, unsigned char *hash) { gcry_md_hash_buffer(GCRY_MD_SHA384, hash, digest, len); + return SSH_OK; } SHA512CTX @@ -124,23 +172,39 @@ sha512_init(void) } void -sha512_update(SHACTX c, const void *data, size_t len) +sha512_ctx_free(SHA512CTX c) { - gcry_md_write(c, data, len); -} - -void -sha512_final(unsigned char *md, SHACTX c) -{ - gcry_md_final(c); - memcpy(md, gcry_md_read(c, 0), SHA512_DIGEST_LEN); gcry_md_close(c); } -void +int +sha512_update(SHACTX c, const void *data, size_t len) +{ + gcry_md_write(c, data, len); + return SSH_OK; +} + +int +sha512_final(unsigned char *md, SHACTX c) +{ + unsigned char *tmp = NULL; + + gcry_md_final(c); + tmp = gcry_md_read(c, 0); + if (tmp == NULL) { + gcry_md_close(c); + return SSH_ERROR; + } + memcpy(md, tmp, SHA512_DIGEST_LEN); + gcry_md_close(c); + return SSH_OK; +} + +int sha512(const unsigned char *digest, size_t len, unsigned char *hash) { gcry_md_hash_buffer(GCRY_MD_SHA512, hash, digest, len); + return SSH_OK; } MD5CTX @@ -153,15 +217,30 @@ md5_init(void) } void +md5_ctx_free(MD5CTX c) +{ + gcry_md_close(c); +} + +int md5_update(MD5CTX c, const void *data, size_t len) { gcry_md_write(c, data, len); + return SSH_OK; } -void +int md5_final(unsigned char *md, MD5CTX c) { + unsigned char *tmp = NULL; + gcry_md_final(c); - memcpy(md, gcry_md_read(c, 0), MD5_DIGEST_LEN); + tmp = gcry_md_read(c, 0); + if (tmp == NULL) { + gcry_md_close(c); + return SSH_ERROR; + } + memcpy(md, tmp, MD5_DIGEST_LEN); gcry_md_close(c); + return SSH_OK; } diff --git a/src/md_mbedcrypto.c b/src/md_mbedcrypto.c index 227e20ab..b3529b4b 100644 --- a/src/md_mbedcrypto.c +++ b/src/md_mbedcrypto.c @@ -64,27 +64,48 @@ sha1_init(void) } void -sha1_update(SHACTX c, const void *data, size_t len) +sha1_ctx_free(SHACTX c) { - mbedtls_md_update(c, data, len); -} - -void -sha1_final(unsigned char *md, SHACTX c) -{ - mbedtls_md_finish(c, md); mbedtls_md_free(c); SAFE_FREE(c); } -void +int +sha1_update(SHACTX c, const void *data, size_t len) +{ + int rc = mbedtls_md_update(c, data, len); + if (rc != 0) { + return SSH_ERROR; + } + return SSH_OK; +} + +int +sha1_final(unsigned char *md, SHACTX c) +{ + int rc = mbedtls_md_finish(c, md); + sha1_ctx_free(c); + if (rc != 0) { + return SSH_ERROR; + } + return SSH_OK; +} + +int sha1(const unsigned char *digest, size_t len, unsigned char *hash) { const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); - if (md_info != NULL) { - mbedtls_md(md_info, digest, len, hash); + int rc; + + if (md_info == NULL) { + return SSH_ERROR; } + rc = mbedtls_md(md_info, digest, len, hash); + if (rc != 0) { + return SSH_ERROR; + } + return SSH_OK; } SHA256CTX @@ -122,27 +143,48 @@ sha256_init(void) } void -sha256_update(SHA256CTX c, const void *data, size_t len) +sha256_ctx_free(SHA256CTX c) { - mbedtls_md_update(c, data, len); -} - -void -sha256_final(unsigned char *md, SHA256CTX c) -{ - mbedtls_md_finish(c, md); mbedtls_md_free(c); SAFE_FREE(c); } -void +int +sha256_update(SHA256CTX c, const void *data, size_t len) +{ + int rc = mbedtls_md_update(c, data, len); + if (rc != 0) { + return SSH_ERROR; + } + return SSH_OK; +} + +int +sha256_final(unsigned char *md, SHA256CTX c) +{ + int rc = mbedtls_md_finish(c, md); + mbedtls_md_free(c); + SAFE_FREE(c); + if (rc != 0) { + return SSH_ERROR; + } + return SSH_OK; +} + +int sha256(const unsigned char *digest, size_t len, unsigned char *hash) { + int rc; const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); - if (md_info != NULL) { - mbedtls_md(md_info, digest, len, hash); + if (md_info == NULL) { + return SSH_ERROR; } + rc = mbedtls_md(md_info, digest, len, hash); + if (rc != 0) { + return SSH_ERROR; + } + return SSH_OK; } SHA384CTX @@ -180,27 +222,48 @@ sha384_init(void) } void -sha384_update(SHA384CTX c, const void *data, size_t len) +sha384_ctx_free(SHA384CTX c) { - mbedtls_md_update(c, data, len); -} - -void -sha384_final(unsigned char *md, SHA384CTX c) -{ - mbedtls_md_finish(c, md); mbedtls_md_free(c); SAFE_FREE(c); } -void +int +sha384_update(SHA384CTX c, const void *data, size_t len) +{ + int rc = mbedtls_md_update(c, data, len); + if (rc != 0) { + return SSH_ERROR; + } + return SSH_OK; +} + +int +sha384_final(unsigned char *md, SHA384CTX c) +{ + int rc = mbedtls_md_finish(c, md); + sha384_ctx_free(c); + if (rc != 0) { + return SSH_ERROR; + } + return SSH_OK; +} + +int sha384(const unsigned char *digest, size_t len, unsigned char *hash) { const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA384); - if (md_info != NULL) { - mbedtls_md(md_info, digest, len, hash); + int rc; + + if (md_info == NULL) { + return SSH_ERROR; } + rc = mbedtls_md(md_info, digest, len, hash); + if (rc != 0) { + return SSH_ERROR; + } + return SSH_OK; } SHA512CTX @@ -237,27 +300,48 @@ sha512_init(void) } void -sha512_update(SHA512CTX c, const void *data, size_t len) +sha512_ctx_free(SHA512CTX c) { - mbedtls_md_update(c, data, len); -} - -void -sha512_final(unsigned char *md, SHA512CTX c) -{ - mbedtls_md_finish(c, md); mbedtls_md_free(c); SAFE_FREE(c); } -void +int +sha512_update(SHA512CTX c, const void *data, size_t len) +{ + int rc = mbedtls_md_update(c, data, len); + if (rc != 0) { + return SSH_ERROR; + } + return SSH_OK; +} + +int +sha512_final(unsigned char *md, SHA512CTX c) +{ + int rc = mbedtls_md_finish(c, md); + sha512_ctx_free(c); + if (rc != 0) { + return SSH_ERROR; + } + return SSH_OK; +} + +int sha512(const unsigned char *digest, size_t len, unsigned char *hash) { const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); - if (md_info != NULL) { - mbedtls_md(md_info, digest, len, hash); + int rc; + + if (md_info == NULL) { + return SSH_ERROR; } + rc = mbedtls_md(md_info, digest, len, hash); + if (rc != 0) { + return SSH_ERROR; + } + return SSH_OK; } MD5CTX @@ -294,15 +378,30 @@ md5_init(void) } void -md5_update(MD5CTX c, const void *data, size_t len) +md5_ctx_free(MD5CTX c) { - mbedtls_md_update(c, data, len); -} - -void -md5_final(unsigned char *md, MD5CTX c) -{ - mbedtls_md_finish(c, md); mbedtls_md_free(c); SAFE_FREE(c); } + +int +md5_update(MD5CTX c, const void *data, size_t len) +{ + int rc = mbedtls_md_update(c, data, len); + if (rc != 0) { + return SSH_ERROR; + } + return SSH_OK; +} + +int +md5_final(unsigned char *md, MD5CTX c) +{ + int rc = mbedtls_md_finish(c, md); + mbedtls_md_free(c); + SAFE_FREE(c); + if (rc != 0) { + return SSH_ERROR; + } + return SSH_OK; +} diff --git a/src/session.c b/src/session.c index c3aaf32f..6b87fe46 100644 --- a/src/session.c +++ b/src/session.c @@ -1047,7 +1047,18 @@ int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash) *hash = NULL; if (session->current_crypto == NULL || session->current_crypto->server_pubkey == NULL) { - ssh_set_error(session,SSH_FATAL,"No current cryptographic context"); + ssh_set_error(session, SSH_FATAL, "No current cryptographic context"); + return SSH_ERROR; + } + + rc = ssh_get_server_publickey(session, &pubkey); + if (rc != SSH_OK) { + return SSH_ERROR; + } + + rc = ssh_pki_export_pubkey_blob(pubkey, &pubkey_blob); + ssh_key_free(pubkey); + if (rc != SSH_OK) { return SSH_ERROR; } @@ -1062,24 +1073,20 @@ int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash) return SSH_ERROR; } - rc = ssh_get_server_publickey(session, &pubkey); + rc = md5_update(ctx, + ssh_string_data(pubkey_blob), + ssh_string_len(pubkey_blob)); if (rc != SSH_OK) { - md5_final(h, ctx); + md5_ctx_free(ctx); SAFE_FREE(h); - return SSH_ERROR; + return rc; } - - rc = ssh_pki_export_pubkey_blob(pubkey, &pubkey_blob); - ssh_key_free(pubkey); - if (rc != SSH_OK) { - md5_final(h, ctx); - SAFE_FREE(h); - return SSH_ERROR; - } - - md5_update(ctx, ssh_string_data(pubkey_blob), ssh_string_len(pubkey_blob)); SSH_STRING_FREE(pubkey_blob); - md5_final(h, ctx); + rc = md5_final(h, ctx); + if (rc != SSH_OK) { + SAFE_FREE(h); + return rc; + } *hash = h; @@ -1200,8 +1207,17 @@ int ssh_get_publickey_hash(const ssh_key key, goto out; } - sha1_update(ctx, ssh_string_data(blob), ssh_string_len(blob)); - sha1_final(h, ctx); + rc = sha1_update(ctx, ssh_string_data(blob), ssh_string_len(blob)); + if (rc != SSH_OK) { + free(h); + sha1_ctx_free(ctx); + goto out; + } + rc = sha1_final(h, ctx); + if (rc != SSH_OK) { + free(h); + goto out; + } *hlen = SHA_DIGEST_LEN; } @@ -1223,8 +1239,17 @@ int ssh_get_publickey_hash(const ssh_key key, goto out; } - sha256_update(ctx, ssh_string_data(blob), ssh_string_len(blob)); - sha256_final(h, ctx); + rc = sha256_update(ctx, ssh_string_data(blob), ssh_string_len(blob)); + if (rc != SSH_OK) { + free(h); + sha256_ctx_free(ctx); + goto out; + } + rc = sha256_final(h, ctx); + if (rc != SSH_OK) { + free(h); + goto out; + } *hlen = SHA256_DIGEST_LEN; } @@ -1254,8 +1279,17 @@ int ssh_get_publickey_hash(const ssh_key key, goto out; } - md5_update(ctx, ssh_string_data(blob), ssh_string_len(blob)); - md5_final(h, ctx); + rc = md5_update(ctx, ssh_string_data(blob), ssh_string_len(blob)); + if (rc != SSH_OK) { + free(h); + md5_ctx_free(ctx); + goto out; + } + rc = md5_final(h, ctx); + if (rc != SSH_OK) { + free(h); + goto out; + } *hlen = MD5_DIGEST_LEN; }