passwordping 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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