passwordping 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,142 @@
1
+ /**
2
+ * The Whirlpool hashing function.
3
+ *
4
+ * The Whirlpool algorithm was developed by
5
+ * Paulo S. L. M. Barreto and Vincent Rijmen.
6
+ *
7
+ * See
8
+ * P.S.L.M. Barreto, V. Rijmen,
9
+ * ``The Whirlpool hashing function,''
10
+ * NESSIE submission, 2000 (tweaked version, 2001),
11
+ * <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip>
12
+ *
13
+ * @version 3.0 (2003.03.12)
14
+ *
15
+ * Modified for use in this software package.
16
+ */
17
+
18
+ #ifndef _WHIRLPOOL_PORTABILITY_H_
19
+ #define _WHIRLPOOL_PORTABILITY_H_
20
+
21
+ /* Definition of minimum-width integer types
22
+ *
23
+ * u8 -> unsigned integer type, at least 8 bits, equivalent to unsigned char
24
+ * u16 -> unsigned integer type, at least 16 bits
25
+ * u32 -> unsigned integer type, at least 32 bits
26
+ *
27
+ * s8, s16, s32 -> signed counterparts of u8, u16, u32
28
+ *
29
+ * Always use macro's T8(), T16() or T32() to obtain exact-width results,
30
+ * i.e., to specify the size of the result of each expression.
31
+ */
32
+
33
+ typedef signed char s8;
34
+ typedef unsigned char u8;
35
+
36
+ #if UINT_MAX >= 4294967295UL
37
+
38
+ typedef signed short s16;
39
+ typedef signed int s32;
40
+ typedef unsigned short u16;
41
+ typedef unsigned int u32;
42
+
43
+ #define ONE32 0xffffffffU
44
+
45
+ #else
46
+
47
+ typedef signed int s16;
48
+ typedef signed long s32;
49
+ typedef unsigned int u16;
50
+ typedef unsigned long u32;
51
+
52
+ #define ONE32 0xffffffffUL
53
+
54
+ #endif
55
+
56
+ #define ONE8 0xffU
57
+ #define ONE16 0xffffU
58
+
59
+ #define T8(x) ((x) & ONE8)
60
+ #define T16(x) ((x) & ONE16)
61
+ #define T32(x) ((x) & ONE32)
62
+
63
+ #ifdef _MSC_VER
64
+ typedef unsigned __int64 u64;
65
+ typedef signed __int64 s64;
66
+ #define LL(v) (v##i64)
67
+ #define ONE64 LL(0xffffffffffffffff)
68
+ #else /* !_MSC_VER */
69
+ typedef unsigned long long u64;
70
+ typedef signed long long s64;
71
+ #define LL(v) (v##ULL)
72
+ #define ONE64 LL(0xffffffffffffffff)
73
+ #endif /* ?_MSC_VER */
74
+ #define T64(x) ((x) & ONE64)
75
+ #define ROTR64(v, n) (((v) >> (n)) | T64((v) << (64 - (n))))
76
+ /*
77
+ * Note: the test is used to detect native 64-bit architectures;
78
+ * if the unsigned long is strictly greater than 32-bit, it is
79
+ * assumed to be at least 64-bit. This will not work correctly
80
+ * on (old) 36-bit architectures (PDP-11 for instance).
81
+ *
82
+ * On non-64-bit architectures, "long long" is used.
83
+ */
84
+
85
+ /*
86
+ * U8TO32_BIG(c) returns the 32-bit value stored in big-endian convention
87
+ * in the unsigned char array pointed to by c.
88
+ */
89
+ #define U8TO32_BIG(c) (((u32)T8(*(c)) << 24) | ((u32)T8(*((c) + 1)) << 16) | ((u32)T8(*((c) + 2)) << 8) | ((u32)T8(*((c) + 3))))
90
+
91
+ /*
92
+ * U8TO32_LITTLE(c) returns the 32-bit value stored in little-endian convention
93
+ * in the unsigned char array pointed to by c.
94
+ */
95
+ #define U8TO32_LITTLE(c) (((u32)T8(*(c))) | ((u32)T8(*((c) + 1)) << 8) | (u32)T8(*((c) + 2)) << 16) | ((u32)T8(*((c) + 3)) << 24))
96
+
97
+ /*
98
+ * U8TO32_BIG(c, v) stores the 32-bit-value v in big-endian convention
99
+ * into the unsigned char array pointed to by c.
100
+ */
101
+ #define U32TO8_BIG(c, v) do { u32 x = (v); u8 *d = (c); d[0] = T8(x >> 24); d[1] = T8(x >> 16); d[2] = T8(x >> 8); d[3] = T8(x); } while (0)
102
+
103
+ /*
104
+ * U8TO32_LITTLE(c, v) stores the 32-bit-value v in little-endian convention
105
+ * into the unsigned char array pointed to by c.
106
+ */
107
+ #define U32TO8_LITTLE(c, v) do { u32 x = (v); u8 *d = (c); d[0] = T8(x); d[1] = T8(x >> 8); d[2] = T8(x >> 16); d[3] = T8(x >> 24); } while (0)
108
+
109
+ /*
110
+ * ROTL32(v, n) returns the value of the 32-bit unsigned value v after
111
+ * a rotation of n bits to the left. It might be replaced by the appropriate
112
+ * architecture-specific macro.
113
+ *
114
+ * It evaluates v and n twice.
115
+ *
116
+ * The compiler might emit a warning if n is the constant 0. The result
117
+ * is undefined if n is greater than 31.
118
+ */
119
+ #define ROTL32(v, n) (T32((v) << (n)) | ((v) >> (32 - (n))))
120
+
121
+ /*
122
+ * Whirlpool-specific definitions.
123
+ */
124
+
125
+ #define DIGESTBYTES WP_DIGEST_SIZE
126
+ #define DIGESTBITS (8*DIGESTBYTES) /* 512 */
127
+
128
+ #define WBLOCKBYTES 64
129
+ #define WBLOCKBITS (8*WBLOCKBYTES) /* 512 */
130
+
131
+ #define LENGTHBYTES 32
132
+ #define LENGTHBITS (8*LENGTHBYTES) /* 256 */
133
+
134
+ struct WP_Struct {
135
+ u8 bitLength[LENGTHBYTES]; /* global number of hashed bits (256-bit counter) */
136
+ u8 buffer[WBLOCKBYTES]; /* buffer of data to hash */
137
+ int bufferBits; /* current number of bits on the buffer */
138
+ int bufferPos; /* current (possibly incomplete) byte slot on the buffer */
139
+ u64 hash[DIGESTBYTES/8]; /* the hashing state */
140
+ };
141
+
142
+ #endif
@@ -0,0 +1,51 @@
1
+ /************************************************
2
+
3
+ whirlpool.c - provides Digest::Whirlpool class
4
+
5
+ Copyright (C) 2006-2013 Akinori MUSHA
6
+
7
+ ************************************************/
8
+
9
+ #ifdef HAVE_RUBY_DIGEST_H
10
+ #include "ruby/digest.h"
11
+ #else
12
+ #include "digest.h"
13
+ #endif
14
+ #include "whirlpool-algorithm.h"
15
+ #include "whirlpool-portability.h"
16
+
17
+ static void WP_Update(WP_Struct * const, const unsigned char * const, size_t);
18
+
19
+ static rb_digest_metadata_t whirlpool = {
20
+ RUBY_DIGEST_API_VERSION,
21
+ WP_DIGEST_SIZE,
22
+ WBLOCKBYTES,
23
+ sizeof(WP_Struct),
24
+ (rb_digest_hash_init_func_t)WP_Init,
25
+ (rb_digest_hash_update_func_t)WP_Update,
26
+ (rb_digest_hash_finish_func_t)WP_Finalize,
27
+ };
28
+
29
+ static void
30
+ WP_Update(WP_Struct * const wp, const unsigned char * const data, size_t len)
31
+ {
32
+ WP_Add(data, len * 8, wp);
33
+ }
34
+
35
+ void
36
+ Init_whirlpool()
37
+ {
38
+ VALUE mDigest, cDigest_Base, cDigest_Whirlpool;
39
+
40
+ rb_require("digest");
41
+
42
+ mDigest = rb_path2class("Digest");
43
+ cDigest_Base = rb_path2class("Digest::Base");
44
+
45
+ cDigest_Whirlpool = rb_define_class_under(mDigest, "Whirlpool", cDigest_Base);
46
+
47
+ // rb_ivar_set(cDigest_Whirlpool, rb_intern("metadata"),
48
+ // Data_Wrap_Struct(rb_cObject, 0, 0, &whirlpool));
49
+ rb_ivar_set(cDigest_Whirlpool, rb_intern("metadata"),
50
+ Data_Wrap_Struct(0, 0, 0, (void *)&whirlpool));
51
+ }
@@ -26,7 +26,7 @@ module PasswordPing
26
26
  def check_credentials(username, password)
27
27
  raise PasswordPingFail, "API key/Secret not set" if !@authString || @authString == ''
28
28
 
29
- response = make_rest_call(@baseURL + Constants::ACCOUNTS_API_PATH + "?username=" + CGI.escape(username), "GET", nil)
29
+ response = make_rest_call(@baseURL + Constants::ACCOUNTS_API_PATH + "?username=" + Hashing.sha256(username), "GET", nil)
30
30
 
31
31
  if (response == "404")
32
32
  return false
@@ -84,7 +84,7 @@ module PasswordPing
84
84
  end
85
85
 
86
86
  def get_exposures_for_user(username)
87
- response = make_rest_call(@baseURL + Constants::EXPOSURES_API_PATH + "?username=" + CGI.escape(username),
87
+ response = make_rest_call(@baseURL + Constants::EXPOSURES_API_PATH + "?username=" + Hashing.sha256(username),
88
88
  "GET", nil)
89
89
 
90
90
  if (response == "404")
@@ -1,8 +1,10 @@
1
1
  require 'passwordping/argon2_wrapper_ffi'
2
2
  require 'digest'
3
- require 'cryptopp'
4
3
  require 'bcrypt'
5
4
  require 'unix_crypt'
5
+ require 'zlib'
6
+ require 'digest/whirlpool'
7
+ require 'base64'
6
8
 
7
9
  module PasswordPing
8
10
  class Hashing
@@ -39,21 +41,19 @@ module PasswordPing
39
41
  end
40
42
 
41
43
  def self.whirlpool(to_hash)
42
- return CryptoPP.digest_factory(:whirlpool, to_hash).digest_hex
44
+ return Digest::Whirlpool.hexdigest(to_hash)
43
45
  end
44
46
 
45
47
  def self.whirlpool_binary(to_hash)
46
- return CryptoPP.digest_factory(:whirlpool, to_hash).digest
48
+ return Digest::Whirlpool.digest(to_hash)
47
49
  end
48
50
 
49
51
  def self.whirlpool_binary_array(to_hash)
50
- return CryptoPP.digest_factory(:whirlpool, to_hash).digest.bytes
52
+ return Digest::Whirlpool.digest(to_hash).bytes
51
53
  end
52
54
 
53
55
  def self.crc32(to_hash)
54
- hash = CryptoPP.digest_factory(:crc32, to_hash).digest_hex
55
- # correct for endian-ness
56
- return hash[6] + hash[7] + hash[4] + hash[5] + hash[2] + hash[3] + hash[0] + hash[1]
56
+ return Zlib.crc32(to_hash, 0).to_s(16)
57
57
  end
58
58
 
59
59
  def self.mybb(to_hash, salt)
@@ -65,7 +65,23 @@ module PasswordPing
65
65
  end
66
66
 
67
67
  def self.bcrypt(to_hash, salt)
68
- return BCrypt::Engine.hash_secret(to_hash, salt)
68
+ # if salt starts with $2y$, first replace with $2a$
69
+ if salt[0..3] == "$2y$"
70
+ y_variant = true
71
+ checked_salt = "$2a$" + salt[4..-1]
72
+ else
73
+ y_variant = false
74
+ checked_salt = salt
75
+ end
76
+
77
+ result = BCrypt::Engine.hash_secret(to_hash, checked_salt)
78
+
79
+ if y_variant
80
+ # replace with $2y$
81
+ result = "$2y$" + result[4..-1]
82
+ end
83
+
84
+ return result
69
85
  end
70
86
 
71
87
  def self.phpbb3(to_hash, salt)
@@ -135,8 +151,49 @@ module PasswordPing
135
151
  return UnixCrypt::MD5.build(to_hash, salt.start_with?("$1$") ? salt[3..salt.length] : salt);
136
152
  end
137
153
 
154
+ def self.custom_algorithm4(to_hash, salt)
155
+ return self.bcrypt(self.md5(to_hash), salt)
156
+ end
157
+
138
158
  def self.argon2(to_hash, salt)
139
- return Argon2Wrapper.hash_argon2d_encode(to_hash, salt, 3, 10, 2, 20)
159
+ time_cost = 3
160
+ mem_cost = 10
161
+ threads = 2
162
+ hash_length = 20
163
+ just_salt = salt
164
+
165
+ #$argon2i$v=19$m=65536,t=2,p=4$c29tZXNhbHQ$RdescudvJCsgt3ub+b+dWRWJTmaaJObG
166
+ if (salt[0..6] == "$argon2")
167
+ # looks like we specified algo info for argon2 in the salt
168
+ salt_values = salt.split("$")
169
+ just_salt = Base64.decode64(salt_values[4])
170
+ cost_params = salt_values[3].split(",")
171
+
172
+ for param in cost_params
173
+ begin
174
+ param_parts = param.split("=")
175
+ if (param_parts[0] == "t")
176
+ time_cost = Integer(param_parts[1])
177
+ elsif (param_parts[0] == "m")
178
+ mem_cost = Math.log2(Integer(param_parts[1])).round
179
+ elsif (param_parts[0] == "p")
180
+ threads = Integer(param_parts[1])
181
+ elsif (param_parts[0] == "l")
182
+ hash_length = Integer(param_parts[1])
183
+ end
184
+ rescue ArgumentError
185
+ # ignore invalid params and just use default
186
+ end
187
+ end
188
+
189
+ if (salt_values[1] == "argon2i")
190
+ return Argon2Wrapper.hash_argon2i_encode(to_hash, just_salt, time_cost, mem_cost, threads, hash_length)
191
+ else
192
+ return Argon2Wrapper.hash_argon2d_encode(to_hash, just_salt, time_cost, mem_cost, threads, hash_length)
193
+ end
194
+ else
195
+ return Argon2Wrapper.hash_argon2d_encode(to_hash, just_salt, time_cost, mem_cost, threads, hash_length)
196
+ end
140
197
  end
141
198
 
142
199
  def self.xor(byte_array1, byte_array2)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  # Standard Gem version constant.
3
3
  module PasswordPing
4
- VERSION = "1.0.0".freeze
4
+ VERSION = "1.0.1".freeze
5
5
  end
@@ -23,12 +23,12 @@ Gem::Specification.new do |spec|
23
23
  spec.add_dependency 'ffi', '~> 1.9'
24
24
  spec.add_dependency 'ffi-compiler', '~> 0.1'
25
25
  spec.add_dependency 'rest-client', '~> 2.0', '>= 2.0.2'
26
- spec.add_dependency 'cryptopp', '~> 0.0', '>= 0.0.5'
27
26
  spec.add_dependency 'bcrypt', '~> 3.1', '>= 3.1.11'
28
27
  spec.add_dependency 'unix-crypt', '~> 1.3'
29
28
 
30
29
  spec.add_development_dependency "bundler", '~> 1.10', '>= 1.10.5'
31
30
  spec.add_development_dependency "rake", '~> 10.4', '>= 10.4.2'
32
31
  spec.add_development_dependency "test-unit", '~> 3.2', '>= 3.2.4'
33
- spec.extensions << 'ext/argon2-wrapper/extconf.rb'
32
+ spec.add_development_dependency "rake-compiler", '~> 1.0', '>= 1.0.4'
33
+ spec.extensions = ['ext/argon2-wrapper/extconf.rb', "ext/digest/whirlpool/extconf.rb" ]
34
34
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: passwordping
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - PasswordPing
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-06-02 00:00:00.000000000 Z
11
+ date: 2017-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -58,26 +58,6 @@ dependencies:
58
58
  - - ">="
59
59
  - !ruby/object:Gem::Version
60
60
  version: 2.0.2
61
- - !ruby/object:Gem::Dependency
62
- name: cryptopp
63
- requirement: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - "~>"
66
- - !ruby/object:Gem::Version
67
- version: '0.0'
68
- - - ">="
69
- - !ruby/object:Gem::Version
70
- version: 0.0.5
71
- type: :runtime
72
- prerelease: false
73
- version_requirements: !ruby/object:Gem::Requirement
74
- requirements:
75
- - - "~>"
76
- - !ruby/object:Gem::Version
77
- version: '0.0'
78
- - - ">="
79
- - !ruby/object:Gem::Version
80
- version: 0.0.5
81
61
  - !ruby/object:Gem::Dependency
82
62
  name: bcrypt
83
63
  requirement: !ruby/object:Gem::Requirement
@@ -172,12 +152,33 @@ dependencies:
172
152
  - - ">="
173
153
  - !ruby/object:Gem::Version
174
154
  version: 3.2.4
155
+ - !ruby/object:Gem::Dependency
156
+ name: rake-compiler
157
+ requirement: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - "~>"
160
+ - !ruby/object:Gem::Version
161
+ version: '1.0'
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: 1.0.4
165
+ type: :development
166
+ prerelease: false
167
+ version_requirements: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - "~>"
170
+ - !ruby/object:Gem::Version
171
+ version: '1.0'
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: 1.0.4
175
175
  description: Ruby library for PasswordPing API
176
176
  email:
177
177
  - support@passwordping.com
178
178
  executables: []
179
179
  extensions:
180
180
  - ext/argon2-wrapper/extconf.rb
181
+ - ext/digest/whirlpool/extconf.rb
181
182
  extra_rdoc_files: []
182
183
  files:
183
184
  - ".gitignore"
@@ -191,6 +192,12 @@ files:
191
192
  - ext/argon2-wrapper/libargon2-wrapper.bundle
192
193
  - ext/argon2-wrapper/libargon2-wrapper.bundle.dSYM/Contents/Info.plist
193
194
  - ext/argon2-wrapper/libargon2-wrapper.bundle.dSYM/Contents/Resources/DWARF/libargon2-wrapper.bundle
195
+ - ext/digest/whirlpool/extconf.rb
196
+ - ext/digest/whirlpool/whirlpool-algorithm.c
197
+ - ext/digest/whirlpool/whirlpool-algorithm.h
198
+ - ext/digest/whirlpool/whirlpool-constants.h
199
+ - ext/digest/whirlpool/whirlpool-portability.h
200
+ - ext/digest/whirlpool/whirlpool.c
194
201
  - ext/phc-winner-argon2/.git
195
202
  - ext/phc-winner-argon2/.gitattributes
196
203
  - ext/phc-winner-argon2/.gitignore
@@ -269,6 +276,7 @@ files:
269
276
  - ext/phc-winner-argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj.filters
270
277
  - ext/phc-winner-argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj
271
278
  - ext/phc-winner-argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj.filters
279
+ - lib/digest/whirlpool.bundle
272
280
  - lib/passwordping.rb
273
281
  - lib/passwordping/argon2_wrapper_ffi.rb
274
282
  - lib/passwordping/constants.rb