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 /src | |
| parent | 69271537031e83c7a96a4221a3a551c0fe7c6075 (diff) | |
Disable hash check if neither OpenSSL nor GNUTLS is installed.
Diffstat (limited to 'src')
| -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 */ | 
