aws-cognito-srp 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://badge.fury.io/rb/aws-cognito-srp.svg?style=flat)](https://rubygems.org/gems/aws-cognito-srp)
|
4
|
+
<!--![CI](https://github.com/pilaf/aws-cognito-srp-ruby/workflows/Ruby/badge.svg)-->
|
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
|