The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
hash.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2016 by Thomas Baumhauer <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include <iostream>
16 #include <string>
17 
18 #include "md5.hpp"
19 #include "hash.hpp"
20 
21 namespace util {
22 
23 const std::string itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" ;
24 const std::string hash_prefix = "$H$";
25 
26 std::array<uint8_t, 16> md5(const std::string& input) {
27  MD5 md5_worker;
28  md5_worker.update(reinterpret_cast<const uint8_t*>(input.data()), input.size());
29  md5_worker.finalize();
30  return md5_worker.raw_digest();
31 }
32 
33 int get_iteration_count(const std::string& hash) {
34  return itoa64.find_first_of(hash[3]);
35 }
36 
38  return hash.substr(4,8);
39 }
40 
41 bool is_valid_hash(const std::string& hash) {
42  if(hash.size() != 34) return false;
43  if(hash.substr(0,3) != hash_prefix) return false;
44 
45  const int iteration_count = get_iteration_count(hash);
46  if(iteration_count < 7 || iteration_count > 30) return false;
47 
48  return true;
49 }
50 
51 std::string encode_hash(const std::array<uint8_t, 16>& input) {
52  std::string encoded_hash;
53 
54  unsigned int i = 0;
55  do {
56  unsigned value = input[i++];
57  encoded_hash.append(itoa64.substr(value & 0x3f,1));
58  if(i < 16)
59  value |= static_cast<int>(input[i]) << 8;
60  encoded_hash.append(itoa64.substr((value >> 6) & 0x3f,1));
61  if(i++ >= 16)
62  break;
63  if(i < 16)
64  value |= static_cast<int>(input[i]) << 16;
65  encoded_hash.append(itoa64.substr((value >> 12) & 0x3f,1));
66  if(i++ >= 16)
67  break;
68  encoded_hash.append(itoa64.substr((value >> 18) & 0x3f,1));
69  } while (i < 16);
70 
71  return encoded_hash;
72 }
73 
74 std::string create_hash(const std::string& password, const std::string& salt, int iteration_count) {
75  iteration_count = 1 << iteration_count;
76 
77  std::array<uint8_t, 16> output = md5(salt + password);
78  do {
79  output = md5(std::string(output.begin(), output.end()).append(password));
80  } while(--iteration_count);
81 
82  return encode_hash(output);
83 }
84 
85 } // namespace util
void update(const uint8_t *input, const uint32_t input_length)
Definition: md5.cpp:75
GLenum GLenum GLenum input
Definition: glew.h:10668
std::array< uint8_t, 16 > md5(const std::string &input)
Returns the MD5 digest for the specified input.
Definition: hash.cpp:26
std::string get_salt(const std::string &hash)
Definition: hash.cpp:37
const std::string hash_prefix
Definition: hash.cpp:24
std::string create_hash(const std::string &password, const std::string &salt, int iteration_count)
Definition: hash.cpp:74
Definition: md5.hpp:48
GLsizei const GLfloat * value
Definition: glew.h:1817
bool is_valid_hash(const std::string &hash)
Definition: hash.cpp:41
static const char * output
Definition: luac.cpp:31
std::array< uint8_t, 16 > raw_digest()
Definition: md5.cpp:159
std::string encode_hash(const std::array< uint8_t, 16 > &input)
Definition: hash.cpp:51
const std::string itoa64
Definition: hash.cpp:23
size_t i
Definition: function.cpp:1057
void finalize()
Definition: md5.cpp:122
GLsizei const GLcharARB ** string
Definition: glew.h:4503
int get_iteration_count(const std::string &hash)
Definition: hash.cpp:33