crypt_checkpass 1 → 2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 189e02218459b7aa4eeb3ff0b6efbecfa49fe612
4
- data.tar.gz: 403f8ca9c8a0e0dec7caff6767b7f5075c56ce8c
3
+ metadata.gz: 3c78a28d5c63b16c2ed28cbc183e8c92885fabd2
4
+ data.tar.gz: 64bcd424fb5ee0bb15e646ec522fdec98c67f106
5
5
  SHA512:
6
- metadata.gz: 5b0c2eb040e52fa190fc04089e42c6d3d1f971be6d925ea10d5bb036ea0685607d3b7702eee8b3b579b5a4afd287860a0bad1fae22153837bc2149952e3b42b6
7
- data.tar.gz: 5fd897d06a1651e583ebaaf39a66a2d76817fb6a2fe26742c5e77ddf6f378222f371a354e1866c6a9e9ca6593d257a96084ee264b3231a2ca932e04055ad902e
6
+ metadata.gz: a6b2ca0a274bc8331b0c2df7b3b774f1c778cc3687705088e1315d480301998ae0f9b9e75813694382ee54c5f6d25815a19cb53e0c84d382086d83c123e8dd68
7
+ data.tar.gz: 607b6f1ae9883d3372e4abaf5a15b87c132cf5972d4c6a1180ec972afce8b6f7aedc2ccaa7d6f6b4aae5ea372e8e13c63978bd6fbe52e71f1471b5ba9b010b4e
data/README.md CHANGED
@@ -18,7 +18,7 @@ Verification:
18
18
  require 'crypt_checkpass'
19
19
  actual = 'p455w0rd'
20
20
  expected = '$5$$D1W6NDlv302WsleruXoUN279B87yf6dFN4ZZhFqV6DD'
21
- crypt_checkpass(actual, expected) or raise 'NG'
21
+ crypt_checkpass?(actual, expected) or raise 'NG'
22
22
  ```
23
23
 
24
24
  Generation:
@@ -25,7 +25,7 @@
25
25
 
26
26
  Gem::Specification.new do |spec|
27
27
  spec.name = 'crypt_checkpass'
28
- spec.version = 1
28
+ spec.version = 2
29
29
  spec.author = 'Urabe, Shyouhei'
30
30
  spec.email = 'shyouhei@ruby-lang.org'
31
31
  spec.summary = 'provides crypt_checkpass / crypt_newhash'
@@ -52,4 +52,5 @@ Gem::Specification.new do |spec|
52
52
  spec.add_development_dependency 'yard'
53
53
  spec.required_ruby_version = '>= 2.0.0'
54
54
  spec.add_runtime_dependency 'consttime_memequal'
55
+ spec.add_runtime_dependency 'phc_string_format'
55
56
  end
@@ -23,7 +23,7 @@
23
23
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  # SOFTWARE.
25
25
 
26
- # Parses what the given _hash_ is, apply the same hasing against _pass_, then
26
+ # Parses what the given _hash_ is, apply the same hashing against _pass_, then
27
27
  # compares the hashed _pass_ and the given _hash_.
28
28
  #
29
29
  # @param pass [String] password string.
@@ -56,7 +56,7 @@ end
56
56
  #
57
57
  # @overload crypt_newhash(password, id:, **kwargs)
58
58
  # At least `:id` argument must be provided this case, which is the name of
59
- # key deliveration function (the ID that the PHC string format says).
59
+ # key derivation function (the ID that the PHC string format says).
60
60
  #
61
61
  # @param password [String] bare, unhashed binary password.
62
62
  # @param id [String] name of the function.
@@ -189,6 +189,21 @@ class << CryptCheckpass
189
189
 
190
190
  # @!endgroup
191
191
 
192
+ # @!group PhcStringFormat wrappers
193
+
194
+ def phcencode id, params, salt, csum
195
+ require 'phc_string_format'
196
+ return PhcStringFormat::Formatter.format \
197
+ id: id, params: params, salt: salt, hash: csum
198
+ end
199
+
200
+ def phcdecode str
201
+ require 'phc_string_format'
202
+ return PhcStringFormat::Formatter.parse str
203
+ end
204
+
205
+ # @!endgroup
206
+
192
207
  def inherited klass
193
208
  super
194
209
  @kdfs.push klass
@@ -38,9 +38,9 @@
38
38
  # - `password` is the raw binary password that you want to digest.
39
39
  #
40
40
  # - `id` is "argon2i" when you want an argon2 hash. Due to underlying
41
- # ruby-argons gem's restriction we do not support other argon2 variants.
41
+ # ruby-argon2 gem's restriction we do not support other argon2 variants.
42
42
  #
43
- # - `m_cost` and `t_cost` are both integer parameter to the algorighm.
43
+ # - `m_cost` and `t_cost` are both integer parameter to the algorithm.
44
44
  #
45
45
  # The generated password hash has following format.
46
46
  #
@@ -77,13 +77,13 @@
77
77
  # hash. Variant "argon2i" seems most widely adopted.
78
78
  #
79
79
  # - `v` is, when available, a number 19. That doesn't mean anything. What
80
- # is important is the _absense_ of that parameter, which means the hash was
81
- # genrated using old argon2 1.0 and shall be out of date.
80
+ # is important is the _absence_ of that parameter, which means the hash was
81
+ # generated using old argon2 1.0 and shall be out of date.
82
82
  #
83
83
  # - `m` is the amount of memory filled by the algorithm (2**m KiB). Memory
84
84
  # consumption depends on this parameter.
85
85
  #
86
- # - `t` is the mumber of passes over the memory. The running time depends
86
+ # - `t` is the number of passes over the memory. The running time depends
87
87
  # linearly on this parameter.
88
88
  #
89
89
  # - `p` is the degree of parallelism, called "lanes" in the C implementation.
@@ -23,8 +23,6 @@
23
23
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  # SOFTWARE.
25
25
 
26
- require_relative 'phc_string_format'
27
-
28
26
  # PBKDF2 is the most beloved algorithm by security professionals.
29
27
  #
30
28
  # ### Newhash:
@@ -112,9 +110,9 @@ class CryptCheckpass::PBKDF2 < CryptCheckpass
112
110
 
113
111
  json = phcdecode hash
114
112
  id = json[:id]
115
- i = json[:params][:i]
113
+ i = json[:params]['i'].to_i
116
114
  salt = json[:salt]
117
- expected = json[:csum]
115
+ expected = json[:hash]
118
116
  dklen = expected.bytesize
119
117
  actual = __derive_key id, i, salt, pass, dklen
120
118
 
@@ -144,8 +142,6 @@ end
144
142
 
145
143
  # helper routines
146
144
  class << CryptCheckpass::PBKDF2
147
- include CryptCheckpass::PHCStringFormat
148
-
149
145
  private
150
146
 
151
147
  if RUBY_VERSION >= '2.3.0'
@@ -24,7 +24,6 @@
24
24
  # SOFTWARE.
25
25
 
26
26
  require 'securerandom'
27
- require_relative 'phc_string_format'
28
27
 
29
28
  # This class is to support RFC7914-related hash variants.
30
29
  #
@@ -59,7 +58,7 @@ require_relative 'phc_string_format'
59
58
  #
60
59
  # - `salt` is the salt string.
61
60
  #
62
- # - `csum` is the checksum strgng.
61
+ # - `csum` is the checksum string.
63
62
  #
64
63
  # All of above fields are represented as hexadecimal numbers.
65
64
  #
@@ -158,16 +157,14 @@ end
158
157
 
159
158
  # helper routines
160
159
  class << CryptCheckpass::Scrypt
161
- include CryptCheckpass::PHCStringFormat
162
-
163
160
  private
164
161
 
165
162
  def checkpass_phc pass, hash
166
163
  require 'consttime_memequal'
167
164
 
168
165
  json = phcdecode hash
169
- ln, r, p = json[:params].values_at :ln, :r, :p
170
- expected = json[:csum]
166
+ ln, r, p = json[:params].values_at("ln", "r", "p").map(&:to_i)
167
+ expected = json[:hash]
171
168
  salt = json[:salt]
172
169
  klen = ::SCrypt::Engine::DEFAULTS[:key_len]
173
170
  actual = ::SCrypt::Engine.scrypt pass, salt, 2 ** ln, r, p, klen
@@ -23,7 +23,7 @@
23
23
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  # SOFTWARE.
25
25
 
26
- # The sha256cyrpt / sha512crypt by Ulrich Drepper. Default for `/etc/shadow`
26
+ # The sha256crypt / sha512crypt by Ulrich Drepper. Default for `/etc/shadow`
27
27
  # of most Linux distributions. Also no security flaws are known at the moment.
28
28
  #
29
29
  # ### Newhash:
@@ -46,7 +46,7 @@
46
46
  #
47
47
  # ### Format:
48
48
  #
49
- # Hash strings generated by sha256cyrpt is construted like this:
49
+ # Hash strings generated by sha256crypt is constructed like this:
50
50
  #
51
51
  # ```ruby
52
52
  # %r{
@@ -63,7 +63,7 @@
63
63
  # }x
64
64
  # ```
65
65
  #
66
- # That of sha512crypt is construted like this:
66
+ # That of sha512crypt is constructed like this:
67
67
  #
68
68
  # ```ruby
69
69
  # %r{
@@ -80,7 +80,7 @@
80
80
  # }x
81
81
  # ```
82
82
  #
83
- # - `id` is 5 for sha256cyrpt, 6 for sha512crypt.
83
+ # - `id` is 5 for sha256crypt, 6 for sha512crypt.
84
84
  #
85
85
  # - `rounds` is, if present, the stretch rounds in decimal integer. Should be
86
86
  # in range of 1,000 to 999,999,999 inclusive.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crypt_checkpass
3
3
  version: !ruby/object:Gem::Version
4
- version: '1'
4
+ version: '2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Urabe, Shyouhei
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-25 00:00:00.000000000 Z
11
+ date: 2018-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -150,6 +150,20 @@ dependencies:
150
150
  - - ">="
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: phc_string_format
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
153
167
  description: Check password hash, like OpenBSD's crypt_checkpass(3) / PHP's password_verify()
154
168
  email: shyouhei@ruby-lang.org
155
169
  executables: []
@@ -171,7 +185,6 @@ files:
171
185
  - lib/crypt_checkpass/argon2.rb
172
186
  - lib/crypt_checkpass/bcrypt.rb
173
187
  - lib/crypt_checkpass/pbkdf2.rb
174
- - lib/crypt_checkpass/phc_string_format.rb
175
188
  - lib/crypt_checkpass/scrypt.rb
176
189
  - lib/crypt_checkpass/sha2.rb
177
190
  homepage: https://github.com/shyouhei/crypt_checkpass
@@ -194,7 +207,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
207
  version: '0'
195
208
  requirements: []
196
209
  rubyforge_project:
197
- rubygems_version: 2.5.2.2
210
+ rubygems_version: 2.2.5
198
211
  signing_key:
199
212
  specification_version: 4
200
213
  summary: provides crypt_checkpass / crypt_newhash
@@ -1,180 +0,0 @@
1
- #! /your/favourite/path/to/ruby
2
- # -*- mode: ruby; coding: utf-8; indent-tabs-mode: nil; ruby-indent-level: 2 -*-
3
- # -*- frozen_string_literal: true -*-
4
- # -*- warn_indent: true -*-
5
-
6
- # Copyright (c) 2018 Urabe, Shyouhei
7
- #
8
- # Permission is hereby granted, free of charge, to any person obtaining a copy
9
- # of this software and associated documentation files (the "Software"), to deal
10
- # in the Software without restriction, including without limitation the rights
11
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
- # copies of the Software, and to permit persons to whom the Software is
13
- # furnished to do so, subject to the following conditions:
14
- #
15
- # The above copyright notice and this permission notice shall be
16
- # included in all copies or substantial portions of the Software.
17
- #
18
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
- # SOFTWARE.
25
-
26
- # Helper module to handle PHC String Format-compatible strings
27
- #
28
- # @note Argon2, which is the winner of PHC, ignores this format and go wild.
29
- # It is highly skeptical that any other hash authors would switch to
30
- # PHC's recommendation.
31
- #
32
- # ### Format
33
- #
34
- # This is how we understand the PHC String Format:
35
- #
36
- # ```ruby
37
- # %r{
38
- # (?<name> [a-z0-9-]{,32} ){0}
39
- # (?<decimal> 0|-?[1-9][0-9]* ){0}
40
- # (?<b64> [a-zA-Z0-9/+.-]* ){0}
41
- #
42
- # (?<id> \g<name> ){0}
43
- # (?<param> \g<name> ){0}
44
- # (?<value> \g<decimal> | \g<b64> ){0}
45
- # (?<salt> \g<b64> ){0}
46
- # (?<csum> \g<b64> ){0}
47
- # (?<pair> \g<param> = \g<value> ){0}
48
- # (?<pairs> \g<pair> (?:[,] \g<pair> )* ){0}
49
- #
50
- # \A [$] \g<id>
51
- # [$] \g<pairs>
52
- # [$] \g<salt>
53
- # [$] \g<csum>
54
- # \z
55
- # }x
56
- # ```
57
- #
58
- # - `id` is the name of the algorithm.
59
- #
60
- # - `pairs` is a set of key-value pair, that are parameters to the
61
- # algorithm. Keys should be human-readable, while values need not be.
62
- #
63
- # - `salt` and `csum` are the salt and checksum strings. Both are encoded in
64
- # what the spec says the "B64" encoding, which is a very slightly modified
65
- # version of RFC4648 (no trailing ==... padding). They both can be
66
- # arbitrary length.
67
- #
68
- # @see https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md
69
- module CryptCheckpass::PHCStringFormat
70
- private
71
-
72
- # B64 encoder
73
- # @param str [String] arbitrary binary string.
74
- # @return [String] str, encoded in B64.
75
- def b64encode str
76
- var = [ str ].pack 'm0'
77
- var.delete! '='
78
- return var
79
- end
80
-
81
- if RUBY_VERSION >= '2.4.0' then
82
- def malloc n
83
- String.new capacity: n
84
- end
85
- else
86
- def malloc n
87
- String.new
88
- end
89
- end
90
-
91
- # B64 decoder
92
- # @param str [String] str, encoded in B64.
93
- # @return [String] decoded binary string
94
- # @raise [ArgumentError] str not in B64 encoding.
95
- def b64decode str
96
- return nil if str.nil?
97
- n, m = str.length.divmod 4
98
- raise ArgumentError, <<-"end".strip, str.length if m == 1
99
- malformed string of %d octets passed.
100
- end
101
- buf = malloc(n * 4)
102
- buf << str
103
- buf << ('=' * ((4 - m) % 4))
104
- return buf.unpack('m0').first
105
- end
106
-
107
- # Form a PHC String Formatted string.
108
- # @return [String] a PHC String Formatted string.
109
- # @param id [String] name of hash algorithm.
110
- # @param params [<<String, Integer>>] hash algorithm parameters.
111
- # @param salt [String] raw binary salt.
112
- # @param csum [String] raw binary checksum
113
- # @note The spec says:
114
- #
115
- # > The function MUST specify the order in which parameters may
116
- # > appear. Producers MUST NOT allow parameters to appear in any
117
- # > other order.
118
- #
119
- # Ensuring that property is up to the caller of this method.
120
- def phcencode id, params, salt, csum
121
- return [
122
- '',
123
- id,
124
- params.map {|a| a.join '=' }.join(','),
125
- b64encode(salt),
126
- b64encode(csum)
127
- ].join('$')
128
- end
129
-
130
- # Decompose a PHC String Formatted string.
131
- # @param str [String] str, encoded in PHC's format.
132
- # @return [Hash] decoded JSON.
133
- def phcdecode str
134
- grammar = %r{
135
- (?<name> [a-z0-9-]{,32} ){0}
136
- (?<decimal> 0|-?[1-9][0-9]* ){0}
137
- (?<b64> [a-zA-Z0-9/+.-]* ){0}
138
-
139
- (?<id> \g<name> ){0}
140
- (?<param> \g<name> ){0}
141
- (?<value> \g<decimal> | \g<b64> ){0}
142
- (?<salt> \g<b64> ){0}
143
- (?<csum> \g<b64> ){0}
144
- (?<pair> \g<param> = \g<value> ){0}
145
- (?<pairs> \g<pair> (?:[,] \g<pair> )* ){0}
146
- }x
147
-
148
- md = %r{
149
- #{grammar}
150
-
151
- \A [$] \g<id>
152
- [$] \g<pairs>
153
- [$] \g<salt>
154
- [$] \g<csum>
155
- \z
156
- }xo.match str
157
- raise "not in PHC String Format: %p", str unless md
158
-
159
- return {
160
- id: md['id'],
161
- params: md['pairs'] \
162
- . split(',', -1) \
163
- . map {|i|
164
- m = /#{grammar}\A\g<pair>\z/o.match i
165
- next [
166
- m['param'],
167
- m['decimal'] ? m['decimal'].to_i : m['b64']
168
- ]
169
- }.each_with_object({}) {|(k, v), h|
170
- h.update(k.to_s.to_sym => v) { |_, w, _|
171
- raise <<-"end".strip, md['params'], k, v, w
172
- %p includes conflicting values for %p: %p versus %p
173
- end
174
- }
175
- },
176
- salt: b64decode(md['salt']),
177
- csum: b64decode(md['csum']),
178
- }
179
- end
180
- end