aws-cognito-srp 0.1.0 → 0.2.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -1
- data/README.md +7 -0
- data/lib/aws/cognito_srp/errors.rb +12 -0
- data/lib/aws/cognito_srp/version.rb +1 -1
- data/lib/aws/cognito_srp.rb +28 -30
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c65852b802463a1355306ddc14aa7d02050a5ff1d4ce2eecd438da11080750a
|
4
|
+
data.tar.gz: 1c411e617dc503d003aa87b0b0ad0df108a54956728e03cc7df59e3323f3fbfc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 738a3d93b4cbc91785e28de959f5c2d62db66aa38c896bff6364a5c4073d3d8e7af717974c075bf6f17ed133769d12c0d958a67e2ded67f58b183e1f6d8a3388
|
7
|
+
data.tar.gz: fe75c97fc0ad291d7503a9f8e8b4b494cdd724315fdaf8e8b244689d834394edc764dc625ddbdc30a5a88cc3cd52720645b58ac3a738b1ac8ae28613891e68cd
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# Aws::CognitoSrp for Ruby
|
2
2
|
|
3
|
+
[](https://rubygems.org/gems/aws-cognito-srp)
|
4
|
+
<!---->
|
5
|
+
|
3
6
|
An unofficial Ruby library implementing
|
4
7
|
[AWS Cognito's SRP authentication flow](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.html#Using-SRP-password-verification-in-custom-authentication-flow).
|
5
8
|
|
@@ -32,6 +35,10 @@ aws_srp = Aws::CognitoSrp.new(
|
|
32
35
|
aws_srp.authenticate
|
33
36
|
```
|
34
37
|
|
38
|
+
## TODO
|
39
|
+
|
40
|
+
[ ] Add specs
|
41
|
+
|
35
42
|
## Development
|
36
43
|
|
37
44
|
After checking out the repo, run `bin/setup` to install dependencies. You can
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "aws/cognito_srp/errors"
|
4
|
+
|
5
|
+
module Aws
|
6
|
+
class CognitoSrp
|
7
|
+
class Error < ::RuntimeError; end
|
8
|
+
class UnexpectedChallenge < Error; end
|
9
|
+
class NewPasswordRequired < Error; end
|
10
|
+
class ValueError < Error; end
|
11
|
+
end
|
12
|
+
end
|
data/lib/aws/cognito_srp.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "aws-sdk-cognitoidentityprovider"
|
4
|
-
require "aws/cognito_srp/version"
|
5
4
|
|
6
5
|
require "openssl"
|
7
6
|
require "digest"
|
7
|
+
require "securerandom"
|
8
|
+
require "base64"
|
9
|
+
|
10
|
+
require "aws/cognito_srp/version"
|
11
|
+
require "aws/cognito_srp/errors"
|
8
12
|
|
9
13
|
module Aws
|
10
14
|
# Client for AWS Cognito Identity Provider using Secure Remote Password (SRP).
|
@@ -77,7 +81,9 @@ module Aws
|
|
77
81
|
}
|
78
82
|
)
|
79
83
|
|
80
|
-
|
84
|
+
unless init_auth_response.challenge_name == PASSWORD_VERIFIER
|
85
|
+
raise UnexpectedChallenge, "Expected Cognito to respond with a #{PASSWORD_VERIFIER} challenge, got #{init_auth_response.challenge_name} instead"
|
86
|
+
end
|
81
87
|
|
82
88
|
challenge_response = process_challenge(init_auth_response.challenge_parameters)
|
83
89
|
|
@@ -87,7 +93,9 @@ module Aws
|
|
87
93
|
challenge_responses: challenge_response
|
88
94
|
)
|
89
95
|
|
90
|
-
|
96
|
+
if auth_response.challenge_name == NEW_PASSWORD_REQUIRED
|
97
|
+
raise NewPasswordRequired, "Cognito responded to password verifier with a #{NEW_PASSWORD_REQUIRED} challenge"
|
98
|
+
end
|
91
99
|
|
92
100
|
auth_response.authentication_result
|
93
101
|
end
|
@@ -101,18 +109,14 @@ module Aws
|
|
101
109
|
|
102
110
|
def calculate_a
|
103
111
|
big_a = @g.pow(@small_a_value, @big_n)
|
104
|
-
if big_a % @big_n == 0
|
105
|
-
raise "Safety check for A failed"
|
106
|
-
end
|
107
|
-
|
112
|
+
raise ValueError, "Safety check for A failed" if big_a % @big_n == 0
|
108
113
|
big_a
|
109
114
|
end
|
110
115
|
|
111
116
|
def get_password_authentication_key(username, password, server_b_value, salt)
|
112
117
|
u_value = calculate_u(@large_a_value, server_b_value)
|
113
|
-
|
114
|
-
|
115
|
-
end
|
118
|
+
|
119
|
+
raise ValueError, "U cannot be zero" if u_value == 0
|
116
120
|
|
117
121
|
username_password = "#{@pool_id.split("_")[1]}#{username}:#{password}"
|
118
122
|
username_password_hash = hash_sha256(username_password)
|
@@ -121,8 +125,7 @@ module Aws
|
|
121
125
|
g_mod_pow_xn = @g.pow(x_value, @big_n)
|
122
126
|
int_value2 = server_b_value - @k * g_mod_pow_xn
|
123
127
|
s_value = int_value2.pow(@small_a_value + u_value * x_value, @big_n)
|
124
|
-
|
125
|
-
hkdf
|
128
|
+
compute_hkdf(hex_to_bytes(pad_hex(s_value)), hex_to_bytes(pad_hex(long_to_hex(u_value))))
|
126
129
|
end
|
127
130
|
|
128
131
|
def process_challenge(challenge_parameters)
|
@@ -131,24 +134,24 @@ module Aws
|
|
131
134
|
srp_b_hex = challenge_parameters.fetch("SRP_B")
|
132
135
|
secret_block_b64 = challenge_parameters.fetch("SECRET_BLOCK")
|
133
136
|
|
134
|
-
timestamp = Time.now.utc.strftime("%a %b %-d %H:%M:%S %Z %Y")
|
137
|
+
timestamp = ::Time.now.utc.strftime("%a %b %-d %H:%M:%S %Z %Y")
|
135
138
|
|
136
139
|
hkdf = get_password_authentication_key(user_id_for_srp, @password, srp_b_hex.to_i(16), salt_hex)
|
137
|
-
secret_block_bytes = Base64.strict_decode64(secret_block_b64)
|
140
|
+
secret_block_bytes = ::Base64.strict_decode64(secret_block_b64)
|
138
141
|
msg = @pool_id.split("_")[1] + user_id_for_srp + secret_block_bytes + timestamp
|
139
|
-
hmac_digest = OpenSSL::HMAC.digest(OpenSSL::Digest.new
|
140
|
-
signature_string = Base64.strict_encode64(hmac_digest).force_encoding('utf-8')
|
142
|
+
hmac_digest = ::OpenSSL::HMAC.digest(::OpenSSL::Digest::SHA256.new, hkdf, msg)
|
143
|
+
signature_string = ::Base64.strict_encode64(hmac_digest).force_encoding('utf-8')
|
141
144
|
|
142
145
|
{
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
146
|
+
TIMESTAMP: timestamp,
|
147
|
+
USERNAME: user_id_for_srp,
|
148
|
+
PASSWORD_CLAIM_SECRET_BLOCK: secret_block_b64,
|
149
|
+
PASSWORD_CLAIM_SIGNATURE: signature_string
|
147
150
|
}
|
148
151
|
end
|
149
152
|
|
150
153
|
def hash_sha256(buf)
|
151
|
-
Digest::SHA256.hexdigest(buf)
|
154
|
+
::Digest::SHA256.hexdigest(buf)
|
152
155
|
end
|
153
156
|
|
154
157
|
def hex_hash(hex_string)
|
@@ -172,16 +175,12 @@ module Aws
|
|
172
175
|
end
|
173
176
|
|
174
177
|
def get_random(nbytes)
|
175
|
-
random_hex = bytes_to_hex(SecureRandom.bytes(nbytes))
|
178
|
+
random_hex = bytes_to_hex(::SecureRandom.bytes(nbytes))
|
176
179
|
hex_to_long(random_hex)
|
177
180
|
end
|
178
181
|
|
179
182
|
def pad_hex(long_int)
|
180
|
-
hash_str =
|
181
|
-
long_int
|
182
|
-
else
|
183
|
-
long_to_hex(long_int)
|
184
|
-
end
|
183
|
+
hash_str = long_int.is_a?(::String) ? long_int : long_to_hex(long_int)
|
185
184
|
|
186
185
|
if hash_str.size % 2 == 1
|
187
186
|
hash_str = "0#{hash_str}"
|
@@ -193,9 +192,9 @@ module Aws
|
|
193
192
|
end
|
194
193
|
|
195
194
|
def compute_hkdf(ikm, salt)
|
196
|
-
prk = OpenSSL::HMAC.digest(OpenSSL::Digest.new
|
195
|
+
prk = ::OpenSSL::HMAC.digest(::OpenSSL::Digest::SHA256.new, salt, ikm)
|
197
196
|
info_bits_update = INFO_BITS + 1.chr.force_encoding('utf-8')
|
198
|
-
hmac_hash = OpenSSL::HMAC.digest(OpenSSL::Digest.new
|
197
|
+
hmac_hash = ::OpenSSL::HMAC.digest(::OpenSSL::Digest::SHA256.new, prk, info_bits_update)
|
199
198
|
hmac_hash[0, 16]
|
200
199
|
end
|
201
200
|
|
@@ -205,4 +204,3 @@ module Aws
|
|
205
204
|
end
|
206
205
|
end
|
207
206
|
end
|
208
|
-
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws-cognito-srp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Viney
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-09-
|
13
|
+
date: 2021-09-20 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: aws-sdk-cognitoidentityprovider
|
@@ -88,6 +88,7 @@ files:
|
|
88
88
|
- bin/setup
|
89
89
|
- lib/aws-cognito-srp.rb
|
90
90
|
- lib/aws/cognito_srp.rb
|
91
|
+
- lib/aws/cognito_srp/errors.rb
|
91
92
|
- lib/aws/cognito_srp/version.rb
|
92
93
|
- lib/aws_cognito_srp.rb
|
93
94
|
homepage: https://github.com/pilaf/aws-cognito-srp-ruby
|