Merge pull request #285 from philsmd/pr-keepass-parser-fix
authorJens Steube <jens.steube@gmail.com>
Sun, 3 Apr 2016 08:15:14 +0000 (10:15 +0200)
committerJens Steube <jens.steube@gmail.com>
Sun, 3 Apr 2016 08:15:14 +0000 (10:15 +0200)
fixed some parser checks for new keepass format (-m 13400)

1  2 
src/shared.c

diff --combined src/shared.c
@@@ -16182,18 -16182,16 +16182,18 @@@ int crammd5_parse_hash (char *input_buf
  
    char *hash_pos = strchr (salt_pos, '$');
  
 -  uint salt_len = hash_pos - salt_pos;
 -
    if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
  
 +  uint salt_len = hash_pos - salt_pos;
 +
    hash_pos++;
  
    uint hash_len = input_len - 10 - salt_len - 1;
  
    // base64 decode salt
  
 +  if (salt_len > 133) return (PARSER_SALT_LENGTH);
 +
    u8 tmp_buf[100] = { 0 };
  
    salt_len = base64_decode (base64_to_int, (const u8 *) salt_pos, salt_len, tmp_buf);
  
    salt->salt_len = salt_len;
  
 -  // base64 decode salt
 +  // base64 decode hash
 +
 +  if (hash_len > 133) return (PARSER_HASH_LENGTH);
  
    memset (tmp_buf, 0, sizeof (tmp_buf));
  
    hash_len = base64_decode (base64_to_int, (const u8 *) hash_pos, hash_len, tmp_buf);
  
 +  if (hash_len < 32 + 1) return (PARSER_SALT_LENGTH);
 +
    uint user_len = hash_len - 32;
  
    const u8 *tmp_hash = tmp_buf + user_len;
@@@ -19180,24 -19174,27 +19180,27 @@@ int keepass_parse_hash (char *input_buf
    keepass->version = atoi (version_pos);
  
    rounds_pos = strchr (version_pos, '*');
-   rounds_pos++;
  
    if (rounds_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
  
+   rounds_pos++;
    salt->salt_iter = (atoi (rounds_pos));
  
    algorithm_pos = strchr (rounds_pos, '*');
-   algorithm_pos++;
  
    if (algorithm_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
  
+   algorithm_pos++;
    keepass->algorithm = atoi (algorithm_pos);
  
    final_random_seed_pos = strchr (algorithm_pos, '*');
-   final_random_seed_pos++;
  
    if (final_random_seed_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
  
+   final_random_seed_pos++;
    keepass->final_random_seed[0] = hex_to_u32 ((const u8 *) &final_random_seed_pos[ 0]);
    keepass->final_random_seed[1] = hex_to_u32 ((const u8 *) &final_random_seed_pos[ 8]);
    keepass->final_random_seed[2] = hex_to_u32 ((const u8 *) &final_random_seed_pos[16]);
  
    transf_random_seed_pos = strchr (final_random_seed_pos, '*');
  
+   if (transf_random_seed_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
    final_random_seed_len = transf_random_seed_pos - final_random_seed_pos;
  
    if (keepass->version == 1 && final_random_seed_len != 32) return (PARSER_SALT_LENGTH);
  
    transf_random_seed_pos++;
  
-   if (transf_random_seed_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
    keepass->transf_random_seed[0] = hex_to_u32 ((const u8 *) &transf_random_seed_pos[ 0]);
    keepass->transf_random_seed[1] = hex_to_u32 ((const u8 *) &transf_random_seed_pos[ 8]);
    keepass->transf_random_seed[2] = hex_to_u32 ((const u8 *) &transf_random_seed_pos[16]);
  
    enc_iv_pos = strchr (transf_random_seed_pos, '*');
  
+   if (enc_iv_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
    transf_random_seed_len = enc_iv_pos - transf_random_seed_pos;
  
    if (transf_random_seed_len != 64) return (PARSER_SALT_LENGTH);
  
    enc_iv_pos++;
  
-   if (enc_iv_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
    keepass->enc_iv[0] = hex_to_u32 ((const u8 *) &enc_iv_pos[ 0]);
    keepass->enc_iv[1] = hex_to_u32 ((const u8 *) &enc_iv_pos[ 8]);
    keepass->enc_iv[2] = hex_to_u32 ((const u8 *) &enc_iv_pos[16]);
    {
      contents_hash_pos = strchr (enc_iv_pos, '*');
  
+     if (contents_hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
      enc_iv_len = contents_hash_pos - enc_iv_pos;
  
      if (enc_iv_len != 32) return (PARSER_SALT_LENGTH);
  
      contents_hash_pos++;
  
-     if (contents_hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
      keepass->contents_hash[0] = hex_to_u32 ((const u8 *) &contents_hash_pos[ 0]);
      keepass->contents_hash[1] = hex_to_u32 ((const u8 *) &contents_hash_pos[ 8]);
      keepass->contents_hash[2] = hex_to_u32 ((const u8 *) &contents_hash_pos[16]);
      /* get length of contents following */
      char *inline_flag_pos = strchr (contents_hash_pos, '*');
  
+     if (inline_flag_pos == NULL) return (PARSER_SALT_LENGTH);
      contents_hash_len = inline_flag_pos - contents_hash_pos;
  
      if (contents_hash_len != 64) return (PARSER_SALT_LENGTH);
  
      contents_len_pos = strchr (inline_flag_pos, '*');
  
+     if (contents_len_pos == NULL) return (PARSER_SALT_LENGTH);
      contents_len_pos++;
  
      contents_len = atoi (contents_len_pos);
  
      contents_pos = strchr (contents_len_pos, '*');
  
+     if (contents_pos == NULL) return (PARSER_SALT_LENGTH);
      contents_pos++;
  
      u32 i;
    {
      expected_bytes_pos = strchr (enc_iv_pos, '*');
  
+     if (expected_bytes_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
      enc_iv_len = expected_bytes_pos - enc_iv_pos;
  
      if (enc_iv_len != 32) return (PARSER_SALT_LENGTH);
  
      expected_bytes_pos++;
  
-     if (expected_bytes_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
      keepass->expected_bytes[0] = hex_to_u32 ((const u8 *) &expected_bytes_pos[ 0]);
      keepass->expected_bytes[1] = hex_to_u32 ((const u8 *) &expected_bytes_pos[ 8]);
      keepass->expected_bytes[2] = hex_to_u32 ((const u8 *) &expected_bytes_pos[16]);
  
      contents_hash_pos = strchr (expected_bytes_pos, '*');
  
+     if (contents_hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
      expected_bytes_len = contents_hash_pos - expected_bytes_pos;
  
      if (expected_bytes_len != 64) return (PARSER_SALT_LENGTH);
  
      contents_hash_pos++;
  
-     if (contents_hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
      keepass->contents_hash[0] = hex_to_u32 ((const u8 *) &contents_hash_pos[ 0]);
      keepass->contents_hash[1] = hex_to_u32 ((const u8 *) &contents_hash_pos[ 8]);
      keepass->contents_hash[2] = hex_to_u32 ((const u8 *) &contents_hash_pos[16]);