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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a9d319dfe478786e4bda431aa7d660c10944737a7d66e95c8c253ab5ec75f691
4
- data.tar.gz: 3741cfe9072feea72cc50d5c41ed5f5111cf9f28df32eaeefdd223908e00e880
3
+ metadata.gz: 9c65852b802463a1355306ddc14aa7d02050a5ff1d4ce2eecd438da11080750a
4
+ data.tar.gz: 1c411e617dc503d003aa87b0b0ad0df108a54956728e03cc7df59e3323f3fbfc
5
5
  SHA512:
6
- metadata.gz: f6f713236d8e76dd635dda2a2437393d7a2b0b009e1f148bf138e53791cf0a1d90e077ffedc7a880f0caf878ab4d493ace2194a43d84b5c96bffcab8c07c5ba2
7
- data.tar.gz: d28cb221df9702987bf37c1f7b1c4fd12af4b74182834435e8ca7833ffc3ad7ba772b3564c883d26d069af167abfa955bc42703d622a794762050617c6077eaa
6
+ metadata.gz: 738a3d93b4cbc91785e28de959f5c2d62db66aa38c896bff6364a5c4073d3d8e7af717974c075bf6f17ed133769d12c0d958a67e2ded67f58b183e1f6d8a3388
7
+ data.tar.gz: fe75c97fc0ad291d7503a9f8e8b4b494cdd724315fdaf8e8b244689d834394edc764dc625ddbdc30a5a88cc3cd52720645b58ac3a738b1ac8ae28613891e68cd
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## Changelog for aws-cognito-srp-ruby
2
2
 
3
- ### [0.1.0] - 2021-09-17
3
+ ### 0.2.0 (September 20, 2021)
4
+
5
+ * Added custom exception classes and better error messages
6
+
7
+ ### 0.1.0 (Septembre 17, 2021)
4
8
 
5
9
  * Initial release
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Aws
4
4
  class CognitoSrp
5
- VERSION = "0.1.0"
5
+ VERSION = "0.2.0"
6
6
  end
7
7
  end
@@ -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
- raise unless init_auth_response.challenge_name == PASSWORD_VERIFIER
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
- raise "new password required" if auth_response.challenge_name == NEW_PASSWORD_REQUIRED
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
- if u_value == 0
114
- raise "U cannot be zero."
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
- hkdf = compute_hkdf(hex_to_bytes(pad_hex(s_value)), hex_to_bytes(pad_hex(long_to_hex(u_value))))
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('sha256'), hkdf, msg)
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
- "TIMESTAMP" => timestamp,
144
- "USERNAME" => user_id_for_srp,
145
- "PASSWORD_CLAIM_SECRET_BLOCK" => secret_block_b64,
146
- "PASSWORD_CLAIM_SIGNATURE" => signature_string
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 = if long_int.is_a?(String)
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('sha256'), salt, ikm)
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('sha256'), prk, info_bits_update)
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.1.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-17 00:00:00.000000000 Z
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