diff options
author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2012-05-26 21:21:53 +0900 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2012-05-26 23:12:02 +0200 |
commit | 7bdb9fba952ea24390b903478aedb5e1615ae2d4 (patch) | |
tree | a81821f8030331ecfb1b94069cd9ff0010915348 | |
parent | 69271537031e83c7a96a4221a3a551c0fe7c6075 (diff) |
Disable hash check if neither OpenSSL nor GNUTLS is installed.
-rw-r--r-- | src/tool_metalink.c | 300 | ||||
-rw-r--r-- | src/tool_metalink.h | 5 | ||||
-rw-r--r-- | src/tool_operate.c | 2 |
3 files changed, 156 insertions, 151 deletions
diff --git a/src/tool_metalink.c b/src/tool_metalink.c index 9a5f9325e..461dbf148 100644 --- a/src/tool_metalink.c +++ b/src/tool_metalink.c @@ -182,25 +182,21 @@ static void SHA256_Final(unsigned char digest[32], SHA256_CTX * ctx) #else -#ifdef USE_SSLEAY - -# ifdef USE_OPENSSL -# include <openssl/md5.h> -# include <openssl/sha.h> -# else -/* TODO What to do if USE_OPENSSL is undefined? */ -# endif - -#else /* USE_SSLEAY */ +#ifdef USE_OPENSSL +# include <openssl/md5.h> +# include <openssl/sha.h> +#else /* USE_OPENSSL */ /* TODO hash functions for other libraries here */ -#endif /* USE_SSLEAY */ +#endif /* USE_OPENSSL */ #endif /* USE_GNUTLS */ #endif /* USE_GNUTLS_NETTLE */ +#ifdef METALINK_HASH_CHECK + const digest_params MD5_DIGEST_PARAMS[] = { { (Curl_digest_init_func) MD5_Init, @@ -274,6 +270,148 @@ int Curl_digest_final(digest_context *context, unsigned char *result) return 0; } +static const metalink_digest_def SHA256_DIGEST_DEF[] = { + {"sha-256", SHA256_DIGEST_PARAMS} +}; + +static const metalink_digest_def SHA1_DIGEST_DEF[] = { + {"sha-1", SHA1_DIGEST_PARAMS} +}; + +static const metalink_digest_def MD5_DIGEST_DEF[] = { + {"md5", MD5_DIGEST_PARAMS} +}; + +/* + * The alias of supported hash functions in the order by preference + * (basically stronger hash comes first). We included "sha-256" and + * "sha256". The former is the name defined in the IANA registry named + * "Hash Function Textual Names". The latter is widely (and + * historically) used in Metalink version 3. + */ +static const metalink_digest_alias digest_aliases[] = { + {"sha-256", SHA256_DIGEST_DEF}, + {"sha256", SHA256_DIGEST_DEF}, + {"sha-1", SHA1_DIGEST_DEF}, + {"sha1", SHA1_DIGEST_DEF}, + {"md5", MD5_DIGEST_DEF}, + {NULL, NULL} +}; + +static unsigned char hex_to_uint(const char *s) +{ + int v[2]; + int i; + for(i = 0; i < 2; ++i) { + v[i] = Curl_raw_toupper(s[i]); + if('0' <= v[i] && v[i] <= '9') { + v[i] -= '0'; + } + else if('A' <= v[i] && v[i] <= 'Z') { + v[i] -= 'A'-10; + } + } + return (unsigned char)((v[0] << 4) | v[1]); +} + +/* + * Check checksum of file denoted by filename. The expected hash value + * is given in hex_hash which is hex-encoded string. + * + * This function returns 1 if it succeeds or one of the following + * integers: + * + * 0: + * Checksum didn't match. + * -1: + * Could not open file; or could not read data from file. + */ +static int check_hash(const char *filename, + const metalink_digest_def *digest_def, + const char *hex_hash, FILE *error) +{ + unsigned char *result; + digest_context *dctx; + int check_ok; + int fd; + size_t i; + fprintf(error, "Checking %s checksum of file %s\n", digest_def->hash_name, + filename); + fd = open(filename, O_RDONLY); + if(fd == -1) { + fprintf(error, "Could not open file %s: %s\n", filename, strerror(errno)); + return -1; + } + dctx = Curl_digest_init(digest_def->dparams); + result = malloc(digest_def->dparams->digest_resultlen); + while(1) { + unsigned char buf[4096]; + ssize_t len = read(fd, buf, sizeof(buf)); + if(len == 0) { + break; + } + else if(len == -1) { + fprintf(error, "Could not read file %s: %s\n", filename, + strerror(errno)); + Curl_digest_final(dctx, result); + close(fd); + return -1; + } + Curl_digest_update(dctx, buf, (unsigned int)len); + } + Curl_digest_final(dctx, result); + check_ok = 1; + for(i = 0; i < digest_def->dparams->digest_resultlen; ++i) { + if(hex_to_uint(&hex_hash[i*2]) != result[i]) { + check_ok = 0; + break; + } + } + free(result); + close(fd); + return check_ok; +} + +int metalink_check_hash(struct Configurable *config, + metalinkfile *mlfile, + const char *filename) +{ + metalink_checksum *chksum; + const metalink_digest_alias *digest_alias; + int rv; + if(mlfile->checksum == NULL) { + return -2; + } + for(digest_alias = digest_aliases; digest_alias->alias_name; + ++digest_alias) { + for(chksum = mlfile->checksum; chksum; chksum = chksum->next) { + if(Curl_raw_equal(digest_alias->alias_name, chksum->hash_name) && + strlen(chksum->hash_value) == + digest_alias->digest_def->dparams->digest_resultlen*2) { + break; + } + } + if(chksum) { + break; + } + } + if(!digest_alias->alias_name) { + fprintf(config->errors, "No supported checksum in Metalink file\n"); + return -2; + } + rv = check_hash(filename, digest_alias->digest_def, + chksum->hash_value, config->errors); + if(rv == 1) { + fprintf(config->errors, "Checksum matched\n"); + } + else if(rv == 0) { + fprintf(config->errors, "Checksum didn't match\n"); + } + return rv; +} + +#endif /* METALINK_HASH_CHECK */ + static metalink_checksum *new_metalink_checksum(const char *hash_name, const char *hash_value) { @@ -474,143 +612,3 @@ int check_metalink_content_type(const char *content_type) { return check_content_type(content_type, "application/metalink+xml"); } - -static const metalink_digest_def SHA256_DIGEST_DEF[] = { - {"sha-256", SHA256_DIGEST_PARAMS} -}; - -static const metalink_digest_def SHA1_DIGEST_DEF[] = { - {"sha-1", SHA1_DIGEST_PARAMS} -}; - -static const metalink_digest_def MD5_DIGEST_DEF[] = { - {"md5", MD5_DIGEST_PARAMS} -}; - -/* - * The alias of supported hash functions in the order by preference - * (basically stronger hash comes first). We included "sha-256" and - * "sha256". The former is the name defined in the IANA registry named - * "Hash Function Textual Names". The latter is widely (and - * historically) used in Metalink version 3. - */ -static const metalink_digest_alias digest_aliases[] = { - {"sha-256", SHA256_DIGEST_DEF}, - {"sha256", SHA256_DIGEST_DEF}, - {"sha-1", SHA1_DIGEST_DEF}, - {"sha1", SHA1_DIGEST_DEF}, - {"md5", MD5_DIGEST_DEF}, - {NULL, NULL} -}; - -static unsigned char hex_to_uint(const char *s) -{ - int v[2]; - int i; - for(i = 0; i < 2; ++i) { - v[i] = Curl_raw_toupper(s[i]); - if('0' <= v[i] && v[i] <= '9') { - v[i] -= '0'; - } - else if('A' <= v[i] && v[i] <= 'Z') { - v[i] -= 'A'-10; - } - } - return (unsigned char)((v[0] << 4) | v[1]); -} - -/* - * Check checksum of file denoted by filename. The expected hash value - * is given in hex_hash which is hex-encoded string. - * - * This function returns 1 if it succeeds or one of the following - * integers: - * - * 0: - * Checksum didn't match. - * -1: - * Could not open file; or could not read data from file. - */ -static int check_hash(const char *filename, - const metalink_digest_def *digest_def, - const char *hex_hash, FILE *error) -{ - unsigned char *result; - digest_context *dctx; - int check_ok; - int fd; - size_t i; - fprintf(error, "Checking %s checksum of file %s\n", digest_def->hash_name, - filename); - fd = open(filename, O_RDONLY); - if(fd == -1) { - fprintf(error, "Could not open file %s: %s\n", filename, strerror(errno)); - return -1; - } - dctx = Curl_digest_init(digest_def->dparams); - result = malloc(digest_def->dparams->digest_resultlen); - while(1) { - unsigned char buf[4096]; - ssize_t len = read(fd, buf, sizeof(buf)); - if(len == 0) { - break; - } - else if(len == -1) { - fprintf(error, "Could not read file %s: %s\n", filename, - strerror(errno)); - Curl_digest_final(dctx, result); - close(fd); - return -1; - } - Curl_digest_update(dctx, buf, (unsigned int)len); - } - Curl_digest_final(dctx, result); - check_ok = 1; - for(i = 0; i < digest_def->dparams->digest_resultlen; ++i) { - if(hex_to_uint(&hex_hash[i*2]) != result[i]) { - check_ok = 0; - break; - } - } - free(result); - close(fd); - return check_ok; -} - -int metalink_check_hash(struct Configurable *config, - metalinkfile *mlfile, - const char *filename) -{ - metalink_checksum *chksum; - const metalink_digest_alias *digest_alias; - int rv; - if(mlfile->checksum == NULL) { - return -2; - } - for(digest_alias = digest_aliases; digest_alias->alias_name; - ++digest_alias) { - for(chksum = mlfile->checksum; chksum; chksum = chksum->next) { - if(Curl_raw_equal(digest_alias->alias_name, chksum->hash_name) && - strlen(chksum->hash_value) == - digest_alias->digest_def->dparams->digest_resultlen*2) { - break; - } - } - if(chksum) { - break; - } - } - if(!digest_alias->alias_name) { - fprintf(config->errors, "No supported checksum in Metalink file\n"); - return -2; - } - rv = check_hash(filename, digest_alias->digest_def, - chksum->hash_value, config->errors); - if(rv == 1) { - fprintf(config->errors, "Checksum matched\n"); - } - else if(rv == 0) { - fprintf(config->errors, "Checksum didn't match\n"); - } - return rv; -} diff --git a/src/tool_metalink.h b/src/tool_metalink.h index 58bb3c439..bffa0deea 100644 --- a/src/tool_metalink.h +++ b/src/tool_metalink.h @@ -27,6 +27,11 @@ struct Configurable; +#if defined(USE_OPENSSL) || defined(USE_GNUTLS) +/* Define 1 if hash check is enabled in Metalink transfer */ +# define METALINK_HASH_CHECK 1 +#endif + typedef struct metalink_checksum { struct metalink_checksum *next; char *hash_name; diff --git a/src/tool_operate.c b/src/tool_operate.c index 3d8303424..c0b66946c 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -1594,12 +1594,14 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) fprintf(config->errors, "Could not parse Metalink file.\n"); } } +# ifdef METALINK_HASH_CHECK else if(metalink && res == CURLE_OK && !metalink_next_res) { int rv = metalink_check_hash(config, mlfile, outs.filename); if(rv == 0) { metalink_next_res = 1; } } +# endif /* METALINK_HASH_CHECK */ #endif /* HAVE_LIBMETALINK */ /* No more business with this output struct */ |