aws-cognito-srp 0.4.0 → 0.5.0

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
  SHA256:
3
- metadata.gz: 6000777b1471345bf83ef454e2147786b46c8960218729c0ef9b33d05bc08634
4
- data.tar.gz: 5b28a08b3614d6dbe6f05a1bc25fd54200a8c90bb6fe8e3a24f97e4afc1bbe80
3
+ metadata.gz: 929d703154eb252230b0ec365cf85bb59e632e62a335bcf63d81c0168f6fe3d3
4
+ data.tar.gz: 2b857f9bcf58f8363eae7ad056de998758bfaf6458ca478d41e4398b57d34a11
5
5
  SHA512:
6
- metadata.gz: d1e507ab4e5a8ce39647a2699ad1bac52a62352c6b2a04d2eb47b12954ae8c8a1f86f26c457583c13f84200064620cbf938381894d302a457b7a2c0468f5f26e
7
- data.tar.gz: 3714f171b5527ed457d2c05e0ff5aece5f96d572e9f48e4fa6412b9cedad85d69ac54432b7e719f7afe0406aa7d135562b0f7446d705d0a4a494f22c48a45bd4
6
+ metadata.gz: 5763f4fac8412527c21ecfb3ae0e283e4cf7be33fc5eadbc94325c83b1b0aa91d34cfc86ebad7895c9f1e1fad93e8c7f8f0f08180f4219d4f78e1ff63d9cf0c1
7
+ data.tar.gz: 13e4d566a91689460b4aca21d48b73a3655d336dfc3e07e0e8c505b107606489581b720d045c72e0ebc2aea27d59a79c76eeba5cb3be77965818b69cb259f10d
@@ -7,14 +7,15 @@ jobs:
7
7
  strategy:
8
8
  fail-fast: false
9
9
  matrix:
10
- ruby: [2.3, 2.4, 2.5, 2.6, 2.7, '3.0']
10
+ os: [ubuntu-latest, macos-latest]
11
+ ruby: [2.4, 2.5, 2.6, 2.7, '3.0', 3.1, 3.2, jruby, truffleruby]
11
12
 
12
- runs-on: ubuntu-latest
13
+ runs-on: ${{ matrix.os }}
13
14
 
14
- name: Test against Ruby ${{ matrix.ruby }}
15
+ name: Test against ${{ matrix.ruby }} on ${{ matrix.os }}
15
16
 
16
17
  steps:
17
- - uses: actions/checkout@v2
18
+ - uses: actions/checkout@v3
18
19
  - name: Set up Ruby
19
20
  uses: ruby/setup-ruby@v1
20
21
  with:
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## Changelog for aws-cognito-srp-ruby
2
2
 
3
+ ### 0.5.0 (February 14❤︎, 2023)
4
+
5
+ * Added support for `client_secret`
6
+
3
7
  ### 0.4.0 (October 1, 2021)
4
8
 
5
9
  * Added `refresh_tokens` method
data/README.md CHANGED
@@ -25,11 +25,12 @@ gem 'aws-cognito-srp'
25
25
  require "aws-cognito-srp"
26
26
 
27
27
  aws_srp = Aws::CognitoSrp.new(
28
- username: "username",
29
- password: "password",
30
- pool_id: "pool-id",
31
- client_id: "client-id",
32
- aws_client: Aws::CognitoIdentityProvider::Client.new(region: "aws-region")
28
+ username: "username",
29
+ password: "password",
30
+ pool_id: "pool-id",
31
+ client_id: "client-id",
32
+ client_secret: "client-secret", # Optional
33
+ aws_client: Aws::CognitoIdentityProvider::Client.new(region: "aws-region")
33
34
  )
34
35
 
35
36
  resp = aws_srp.authenticate
@@ -44,9 +45,23 @@ resp.refresh_token
44
45
  new_tokens = aws_srp.refresh_tokens(resp.refresh_token)
45
46
  ```
46
47
 
48
+ In case you need access to the `USER_ID_FOR_SRP` value from the auth response,
49
+ you can do so by calling `aws_srp.user_id_for_srp` *after* the initial auth
50
+ (`aws_srp` being the same as in the code example above).
51
+
52
+ If you're using a `client_secret` and calling `#refresh_tokens` in a different
53
+ instance than the one that performed the initial call to `#authenticate` you
54
+ will have to pass the `USER_ID_FOR_SRP` value as a keyword argument:
55
+
56
+ ```ruby
57
+ new_tokens = aws_srp.refresh_token(resp.refresh_token,
58
+ user_id_for_srp: your_user_id_for_srp)
59
+ ```
60
+
47
61
  ## Supported rubies
48
62
 
49
- This gem is tested against and supports Ruby 2.3, 2.4, 2.5, 2.6, 2.7 and 3.0.
63
+ This gem is tested against and supports Ruby 2.4 through 3.2, JRuby and
64
+ TruffleRuby.
50
65
 
51
66
  ## Development
52
67
 
@@ -20,11 +20,13 @@ Gem::Specification.new do |spec|
20
20
  end
21
21
  spec.require_paths = ["lib"]
22
22
 
23
+ spec.required_ruby_version = '>= 2.4.0'
24
+
23
25
  spec.add_dependency "aws-sdk-cognitoidentityprovider"
24
26
 
25
- spec.add_development_dependency "bundler", "~> 2.2.0"
27
+ spec.add_development_dependency "bundler", "~> 2.2"
26
28
  spec.add_development_dependency "rake", "~> 13.0"
27
- spec.add_development_dependency "ox", "~> 2.14.0"
29
+ spec.add_development_dependency "nokogiri", "~> 1.9"
28
30
  spec.add_development_dependency "rspec", "~> 3.0"
29
31
  spec.add_development_dependency "pry"
30
32
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Aws
4
4
  class CognitoSrp
5
- VERSION = "0.4.0"
5
+ VERSION = "0.5.0"
6
6
  end
7
7
  end
@@ -24,19 +24,6 @@ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.5")
24
24
  using IntegerWithPow
25
25
  end
26
26
 
27
- if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.4")
28
- module StringWithUnpack1
29
- refine String do
30
- # String#unpack1 was introduced in Ruby 2.4
31
- def unpack1(fmt)
32
- unpack(fmt)[0]
33
- end
34
- end
35
- end
36
-
37
- using StringWithUnpack1
38
- end
39
-
40
27
  module Aws
41
28
  # Client for AWS Cognito Identity Provider using Secure Remote Password (SRP).
42
29
  #
@@ -85,12 +72,15 @@ module Aws
85
72
 
86
73
  INFO_BITS = 'Caldera Derived Key'
87
74
 
88
- def initialize(username:, password:, pool_id:, client_id:, aws_client:)
75
+ attr_reader :user_id_for_srp
76
+
77
+ def initialize(username:, password:, pool_id:, client_id:, aws_client:, client_secret: nil)
89
78
  @username = username
90
79
  @password = password
91
80
  @pool_id = pool_id
92
81
  @client_id = client_id
93
82
  @aws_client = aws_client
83
+ @client_secret = client_secret
94
84
 
95
85
  @big_n = hex_to_long(N_HEX)
96
86
  @g = hex_to_long(G_HEX)
@@ -100,13 +90,16 @@ module Aws
100
90
  end
101
91
 
102
92
  def authenticate
93
+ auth_parameters = {
94
+ USERNAME: @username,
95
+ SRP_A: long_to_hex(@large_a_value),
96
+ SECRET_HASH: @client_secret && secret_hash(@username)
97
+ }.compact
98
+
103
99
  init_auth_response = @aws_client.initiate_auth(
104
100
  client_id: @client_id,
105
101
  auth_flow: USER_SRP_AUTH,
106
- auth_parameters: {
107
- USERNAME: @username,
108
- SRP_A: long_to_hex(@large_a_value)
109
- }
102
+ auth_parameters: auth_parameters
110
103
  )
111
104
 
112
105
  unless init_auth_response.challenge_name == PASSWORD_VERIFIER
@@ -114,12 +107,15 @@ module Aws
114
107
  end
115
108
 
116
109
  challenge_response = process_challenge(init_auth_response.challenge_parameters)
110
+ hash = @client_secret && secret_hash(@user_id_for_srp)
117
111
 
118
- auth_response = @aws_client.respond_to_auth_challenge(
112
+ params = {
119
113
  client_id: @client_id,
120
114
  challenge_name: PASSWORD_VERIFIER,
121
- challenge_responses: challenge_response
122
- )
115
+ challenge_responses: challenge_response.merge(SECRET_HASH: hash).compact
116
+ }
117
+
118
+ auth_response = @aws_client.respond_to_auth_challenge(params)
123
119
 
124
120
  if auth_response.challenge_name == NEW_PASSWORD_REQUIRED
125
121
  raise NewPasswordRequired, "Cognito responded to password verifier with a #{NEW_PASSWORD_REQUIRED} challenge"
@@ -128,13 +124,16 @@ module Aws
128
124
  auth_response.authentication_result
129
125
  end
130
126
 
131
- def refresh_tokens(refresh_token)
127
+ def refresh_tokens(refresh_token, user_id_for_srp: @user_id_for_srp)
128
+ auth_parameters = {
129
+ REFRESH_TOKEN: refresh_token,
130
+ SECRET_HASH: @client_secret && secret_hash(user_id_for_srp)
131
+ }.compact
132
+
132
133
  resp = @aws_client.initiate_auth(
133
134
  client_id: @client_id,
134
135
  auth_flow: REFRESH_TOKEN,
135
- auth_parameters: {
136
- REFRESH_TOKEN: refresh_token
137
- }
136
+ auth_parameters: auth_parameters
138
137
  )
139
138
 
140
139
  resp.authentication_result
@@ -170,22 +169,22 @@ module Aws
170
169
  end
171
170
 
172
171
  def process_challenge(challenge_parameters)
173
- user_id_for_srp = challenge_parameters.fetch("USER_ID_FOR_SRP")
172
+ @user_id_for_srp = challenge_parameters.fetch("USER_ID_FOR_SRP")
174
173
  salt_hex = challenge_parameters.fetch("SALT")
175
174
  srp_b_hex = challenge_parameters.fetch("SRP_B")
176
175
  secret_block_b64 = challenge_parameters.fetch("SECRET_BLOCK")
177
176
 
178
177
  timestamp = ::Time.now.utc.strftime("%a %b %-d %H:%M:%S %Z %Y")
179
178
 
180
- hkdf = get_password_authentication_key(user_id_for_srp, @password, srp_b_hex.to_i(16), salt_hex)
179
+ hkdf = get_password_authentication_key(@user_id_for_srp, @password, srp_b_hex.to_i(16), salt_hex)
181
180
  secret_block_bytes = ::Base64.strict_decode64(secret_block_b64)
182
- msg = @pool_id.split("_")[1] + user_id_for_srp + secret_block_bytes + timestamp
181
+ msg = @pool_id.split("_")[1] + @user_id_for_srp + secret_block_bytes + timestamp
183
182
  hmac_digest = ::OpenSSL::HMAC.digest(::OpenSSL::Digest::SHA256.new, hkdf, msg)
184
183
  signature_string = ::Base64.strict_encode64(hmac_digest).force_encoding('utf-8')
185
184
 
186
185
  {
187
186
  TIMESTAMP: timestamp,
188
- USERNAME: user_id_for_srp,
187
+ USERNAME: @user_id_for_srp,
189
188
  PASSWORD_CLAIM_SECRET_BLOCK: secret_block_b64,
190
189
  PASSWORD_CLAIM_SIGNATURE: signature_string
191
190
  }
@@ -242,5 +241,9 @@ module Aws
242
241
  u_hex_hash = hex_hash(pad_hex(big_a) + pad_hex(big_b))
243
242
  hex_to_long(u_hex_hash)
244
243
  end
244
+
245
+ def secret_hash(username)
246
+ Base64.strict_encode64(OpenSSL::HMAC.digest('sha256', @client_secret, username + @client_id))
247
+ end
245
248
  end
246
249
  end
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.0
4
+ version: 0.5.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-10-01 00:00:00.000000000 Z
13
+ date: 2023-02-14 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: aws-sdk-cognitoidentityprovider
@@ -32,14 +32,14 @@ dependencies:
32
32
  requirements:
33
33
  - - "~>"
34
34
  - !ruby/object:Gem::Version
35
- version: 2.2.0
35
+ version: '2.2'
36
36
  type: :development
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
40
  - - "~>"
41
41
  - !ruby/object:Gem::Version
42
- version: 2.2.0
42
+ version: '2.2'
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: rake
45
45
  requirement: !ruby/object:Gem::Requirement
@@ -55,19 +55,19 @@ dependencies:
55
55
  - !ruby/object:Gem::Version
56
56
  version: '13.0'
57
57
  - !ruby/object:Gem::Dependency
58
- name: ox
58
+ name: nokogiri
59
59
  requirement: !ruby/object:Gem::Requirement
60
60
  requirements:
61
61
  - - "~>"
62
62
  - !ruby/object:Gem::Version
63
- version: 2.14.0
63
+ version: '1.9'
64
64
  type: :development
65
65
  prerelease: false
66
66
  version_requirements: !ruby/object:Gem::Requirement
67
67
  requirements:
68
68
  - - "~>"
69
69
  - !ruby/object:Gem::Version
70
- version: 2.14.0
70
+ version: '1.9'
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: rspec
73
73
  requirement: !ruby/object:Gem::Requirement
@@ -132,14 +132,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
132
132
  requirements:
133
133
  - - ">="
134
134
  - !ruby/object:Gem::Version
135
- version: '0'
135
+ version: 2.4.0
136
136
  required_rubygems_version: !ruby/object:Gem::Requirement
137
137
  requirements:
138
138
  - - ">="
139
139
  - !ruby/object:Gem::Version
140
140
  version: '0'
141
141
  requirements: []
142
- rubygems_version: 3.0.6
142
+ rubygems_version: 3.3.3
143
143
  signing_key:
144
144
  specification_version: 4
145
145
  summary: AWS Cognito SRP auth for Ruby