touchpass 0.0.8.1 → 0.0.8.16

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.
Files changed (38) hide show
  1. data/.gitignore +2 -0
  2. data/Gemfile +6 -0
  3. data/Gemfile.lock +27 -12
  4. data/Rakefile +20 -1
  5. data/app/assets/images/touchpass/buttons/cancelling.png +0 -0
  6. data/app/assets/images/touchpass/buttons/unverified.png +0 -0
  7. data/app/assets/images/touchpass/buttons/verified.png +0 -0
  8. data/app/assets/images/touchpass/buttons/verify.png +0 -0
  9. data/app/assets/images/touchpass/buttons/verifying.png +0 -0
  10. data/app/assets/images/touchpass/cross.png +0 -0
  11. data/app/assets/images/touchpass/loading.gif +0 -0
  12. data/app/assets/images/touchpass/tick.png +0 -0
  13. data/app/assets/images/touchpass/touchpass-logo.jpg +0 -0
  14. data/app/assets/javascripts/touchpass/index.js +1 -0
  15. data/app/assets/javascripts/touchpass/jquery.touchpass-0.0.1.js +199 -0
  16. data/app/assets/stylesheets/touchpass/index.css +1 -0
  17. data/app/assets/stylesheets/touchpass/widget.css +17 -0
  18. data/app/controllers/touchpass/verifications_controller.rb +10 -6
  19. data/bin/tpcli.rb +29 -21
  20. data/bin/tpcrypt.rb +38 -0
  21. data/config/routes.rb +2 -2
  22. data/lib/touchpass/client.rb +33 -81
  23. data/lib/touchpass/crypt.rb +29 -6
  24. data/lib/touchpass/prp.rb +9 -6
  25. data/lib/touchpass/{device.rb → rp/device.rb} +5 -2
  26. data/lib/touchpass/rp/response.rb +34 -0
  27. data/lib/touchpass/rp/verification.rb +53 -0
  28. data/lib/touchpass/verification.rb +119 -86
  29. data/lib/touchpass/version.rb +1 -1
  30. data/lib/touchpass.rb +27 -5
  31. data/spec/curl.touchpass_client_spec-workingcontent.txt +268 -0
  32. data/spec/spec_helper.rb +9 -0
  33. data/spec/touchpass_client_spec.rb +42 -48
  34. data/spec/touchpass_crypt_spec.rb +27 -0
  35. data/spec/touchpass_rp_verification_spec.rb +52 -0
  36. data/spec/touchpass_spec.rb +12 -0
  37. data/spec/touchpass_verification_spec.rb +26 -0
  38. metadata +66 -14
@@ -11,6 +11,7 @@ require 'base64'
11
11
  require 'pp'
12
12
  require 'cgi'
13
13
  require 'json'
14
+ require 'securerandom'
14
15
 
15
16
  module Touchpass
16
17
 
@@ -103,12 +104,13 @@ module Touchpass
103
104
  # Collect attributes of new device
104
105
  device_attributes = params.merge({
105
106
  :udid => params[:udid],
107
+ :app_id => params[:app_id],
106
108
  :name => params[:name],
107
109
  :pub_key => crypt.public_key,
108
110
  :messaging_type => params[:messaging_type],
109
- :messaging_value => params[:messaging_value],
111
+ :messaging_value => params[:messaging_value]
110
112
  })
111
- http_options = standard_http_options(device_attributes, %W{udid name pub_key messaging_type messaging_value})
113
+ http_options = standard_http_options(device_attributes, %W{udid app_id name pub_key messaging_type messaging_value})
112
114
 
113
115
  # Provision the new device with the Touchpass server
114
116
  new_device = submit_request("post", "#{@hostname}/#{params[:username]}/devices.#{@output}", http_options)
@@ -179,77 +181,21 @@ module Touchpass
179
181
  end
180
182
 
181
183
  # Create a new verification
182
- # needs: :to_party, :api_key; uses: :message, :address (for LV), :resolution (for LV)
184
+ # needs: :to_party, :api_key
185
+ # uses:
186
+ # :address (for LV), :resolution (for LV)
187
+ # :message, :message_post_verification
183
188
  def create_verification(params)
184
- http_options = standard_http_options(params, %W{to_party})
185
- message = params[:message]
186
- address = params[:address]
189
+ http_options = standard_http_options(params, %W{to_party to_device_id to_app_id})
187
190
 
188
191
  # Get the list of verifying party devices so we can encrypt data for them using each device's public key
189
192
  response = submit_request("get", "#{@hostname}/#{params[:to_party]}/devices.json",
190
193
  standard_http_options(params))
191
194
  vp_devices = response["devices"]
192
195
 
193
- # Generate token
194
- token = Crypt.salt
195
- hashed_token = Crypt.encrypt(token)
196
- http_options[:body][:claimed_token] = hashed_token
197
-
198
- if !vp_devices.nil? and (vp_devices.is_a? Array and !vp_devices.empty?)
199
-
200
- # Encrypt message using each verifying party's (to_party) device public keys
201
- if !message.nil?
202
- vp_devices.each_with_index do |device, index|
203
- device_id = device["id"]
204
- pub_key_str = device["pub_key"]
205
- public_key = Crypt.read_key(pub_key_str)
206
- crypted_message = Base64.encode64(public_key.public_encrypt(message))
207
- http_options[:body]["crypted_messages[#{index}][device_id]"] = device_id
208
- http_options[:body]["crypted_messages[#{index}][value]"] = crypted_message
209
- end
210
- end
211
-
212
- # Encrypt token using each verifying party's (to_party) device public keys
213
- crypted_tokens = []
214
- vp_devices.each_with_index do |device, index|
215
- device_id = device["id"]
216
- pub_key_str = device["pub_key"]
217
- public_key = Crypt.read_key(pub_key_str)
218
- crypted_token = Base64.encode64(public_key.public_encrypt(token)) # per-transaction token generated by Crypt.salt above
219
- http_options[:body]["crypted_tokens[#{index}][device_id]"] = device_id
220
- http_options[:body]["crypted_tokens[#{index}][value]"] = crypted_token
221
- end
222
- end
223
-
224
- # Encrypt prp-hash using verifying_party (to_party) devices
225
- if !address.nil? # For location verification
226
- http_options[:body][:location_verification] = true
227
-
228
- # Convert address to PRP
229
- resolution = options[:resolution] || "LOCAL" # Resolution used to calculate PRP
230
- http_options[:body][:resolution] = resolution
231
- prp = Proximity::PRP.new(:address => params[:address], :resolution => resolution)
232
- # puts prp.print_bbox # for debugging
233
-
234
- # Generate random salt
235
- salt = Crypt.salt
236
- # puts "Using salt: #{salt}" # for debugging
237
-
238
- # Encrypt PRP using salt
239
- claimed_prp = prp.encrypt(salt)
240
- http_options[:body][:claimed_prp] = claimed_prp
241
-
242
- # Encrypt salt using verifiying_party (to_party) devices
243
- crypted_salts = []
244
- vp_devices.each_with_index do |device, index|
245
- device_id = device["id"]
246
- pub_key_str = device["pub_key"]
247
- public_key = Crypt.read_key(pub_key_str)
248
- crypted_salt = Base64.encode64(public_key.public_encrypt(salt))
249
- http_options[:body]["crypted_salts[#{index}][device_id]"] = device_id
250
- http_options[:body]["crypted_salts[#{index}][value]"] = crypted_salt
251
- end
252
- end
196
+ # create a verification object
197
+ verification = Touchpass::Verification.new(vp_devices, params)
198
+ http_options[:body].merge!(verification.http_params)
253
199
 
254
200
  submit_request("post", "#{@hostname}/verifications.#{@output}", http_options)
255
201
  end
@@ -295,25 +241,19 @@ module Touchpass
295
241
  def update_verification(params)
296
242
  # Call show verification to get the crypted salts and resolution for the verification
297
243
  # Note: crypted salts and resolution are also returned in the list verifications response
298
- http_options = standard_http_options(params)
299
-
300
- verification = submit_request("get", "#{@hostname}/verifications/#{params[:id]}.json", http_options)
301
- crypted_tokens = verification["crypted_tokens"]
302
- crypted_salts = verification["crypted_salts"]
303
- resolution = verification["resolution"]
244
+ http_options = standard_http_options(params, %W{id})
304
245
 
305
- token = decrypt_salt(crypted_tokens, params[:device_id], self.api_key)
306
- hashed_token = Crypt.encrypt(token)
246
+ verification = get_verification(params)
307
247
 
308
- http_options = standard_http_options(params, %W{id})
309
- http_options[:body][:verified_token] = hashed_token
248
+ token = decrypt_salt(verification["crypted_tokens"], params[:device_id], self.api_key)
249
+ http_options[:body][:verified_token] = Crypt.hash(token) unless token.nil?
310
250
 
311
251
  # Generate verified PRP for location verification
312
252
  if !params[:address].nil?
313
- prp = Proximity::PRP.new(:address => params[:address], :resolution => resolution)
253
+ prp = Proximity::PRP.new(:address => params[:address], :resolution => verification["resolution"])
314
254
  # puts prp.print_bbox # for debugging
315
255
 
316
- salt = decrypt_salt(crypted_salts, params[:device_id], self.api_key)
256
+ salt = decrypt_salt(verification["crypted_salts"], params[:device_id], self.api_key)
317
257
  # puts "Using salt: #{salt}"
318
258
  verified_prp = prp.encrypt(salt)
319
259
 
@@ -327,15 +267,27 @@ module Touchpass
327
267
  # Cancel an existing verification
328
268
  # needs: :api_key, :id
329
269
  def cancel_verification(params)
270
+ http_options = standard_http_options(params)
271
+ verification = get_verification(params)
272
+
273
+ token = decrypt_salt(verification["crypted_tokens"], params[:device_id], self.api_key)
274
+ http_options[:body][:verified_token] = Crypt.hash(token) unless token.nil?
275
+
330
276
  submit_request("put", "#{@hostname}/verifications/#{params[:id]}/cancel.#{@output}",
331
- standard_http_options(params))
277
+ http_options)
332
278
  end
333
279
 
334
280
  # Reject a verification
335
- # needs: :api_keu, :id
281
+ # needs: :api_key, :id
336
282
  def reject_verification(params)
283
+ http_options = standard_http_options(params)
284
+ verification = get_verification(params)
285
+
286
+ token = decrypt_salt(verification["crypted_tokens"], params[:device_id], self.api_key)
287
+ http_options[:body][:verified_token] = Crypt.hash(token) unless token.nil?
288
+
337
289
  submit_request("put", "#{@hostname}/verifications/#{params[:id]}/reject.#{@output}",
338
- standard_http_options(params))
290
+ http_options)
339
291
  end
340
292
 
341
293
  private
@@ -1,9 +1,9 @@
1
-
2
1
  module Touchpass
3
2
  class Crypt
4
3
  # Encryption method
5
4
  # Options: :md5, :sha1, :sha256, :sha512
6
- CRYPTO_PROVIDER = :sha256
5
+ HASH_CRYPTO_PROVIDER = :sha256
6
+ ENCRYPTION_ALGORITHM = 'AES-128-CBC'
7
7
 
8
8
  def self.salt(length=10)
9
9
  seeds = ('a'..'z').to_a
@@ -18,9 +18,32 @@ module Touchpass
18
18
  salt_string
19
19
  end
20
20
 
21
- def self.encrypt(string)
21
+ def self.generate_encryption_key
22
+ crypt = OpenSSL::Cipher.new(ENCRYPTION_ALGORITHM)
23
+ crypt.encrypt
24
+ crypt.random_key
25
+ end
26
+
27
+ def self.cipher(mode, data, key)
28
+ return nil unless data
29
+ crypt = OpenSSL::Cipher.new(ENCRYPTION_ALGORITHM).send(mode)
30
+ crypt.key = key
31
+ crypt.padding = 1
32
+ crypt.update(data) << crypt.final
33
+ end
34
+
35
+ def self.encrypt(data, key)
36
+ cipher(:encrypt, data, key)
37
+ end
38
+
39
+ def self.decrypt(data, key)
40
+ cipher(:decrypt, data, key)
41
+ end
42
+
43
+ # hex digest
44
+ def self.hash(string)
22
45
  crypto_provider = nil
23
- case CRYPTO_PROVIDER
46
+ case HASH_CRYPTO_PROVIDER
24
47
  when :md5
25
48
  require 'digest/md5' unless defined?(Digest::MD5)
26
49
  crypto_provider = Digest::MD5
@@ -37,11 +60,11 @@ module Touchpass
37
60
  return crypto_provider.hexdigest(string)
38
61
  end
39
62
 
40
- def self.read_key(pem)
63
+ def self.read_rsa_key(pem)
41
64
  begin
42
65
  return OpenSSL::PKey::RSA.new(pem)
43
66
  rescue
44
- puts "Unable to read key."
67
+ warn "Unable to read key."
45
68
  end
46
69
  return nil
47
70
  end
data/lib/touchpass/prp.rb CHANGED
@@ -144,11 +144,14 @@ module Touchpass
144
144
 
145
145
  # Returns the hashed representation of the bounding coordinates
146
146
  def encrypt(salt=nil)
147
- crypted_1 = encrypt_point(@bounding_coordinates[:top_left], salt)
148
- crypted_2 = encrypt_point(@bounding_coordinates[:top_right], salt)
149
- crypted_3 = encrypt_point(@bounding_coordinates[:bottom_right], salt)
150
- crypted_4 = encrypt_point(@bounding_coordinates[:bottom_left], salt)
151
- @crypted_coordinates = crypted_1 + crypted_2 + crypted_3 + crypted_4
147
+ if @bounding_coordinates
148
+ crypted_1 = encrypt_point(@bounding_coordinates[:top_left], salt)
149
+ crypted_2 = encrypt_point(@bounding_coordinates[:top_right], salt)
150
+ crypted_3 = encrypt_point(@bounding_coordinates[:bottom_right], salt)
151
+ crypted_4 = encrypt_point(@bounding_coordinates[:bottom_left], salt)
152
+ @crypted_coordinates = crypted_1 + crypted_2 + crypted_3 + crypted_4
153
+ end
154
+
152
155
  return @crypted_coordinates
153
156
  end
154
157
 
@@ -170,7 +173,7 @@ module Touchpass
170
173
  # that are coming from 3,240,000 values (ie 1,800*1,800) as opposed to 2 hashes derived from a set of 1,800
171
174
  # possible values.
172
175
  str_to_encrypt = (lat.to_s) + "," + (lng.to_s) + salt.to_s
173
- return Touchpass::Crypt.encrypt(str_to_encrypt)
176
+ return Touchpass::Crypt.hash(str_to_encrypt)
174
177
  end
175
178
 
176
179
  def self.truncate_size(resolution)
@@ -11,8 +11,11 @@ module Touchpass
11
11
  def get_all(user)
12
12
  http_options = { :body => {}, :headers => { Touchpass::Client::API_KEY_HEADER => Touchpass.api_key } }
13
13
  response = self.class.get("/#{user}/devices.json", http_options)
14
- return response.parsed_response["devices"]
14
+
15
+ tp_response = Touchpass::Rp::Response.new(response)
16
+ tp_response.response = tp_response['devices'] || []
17
+ tp_response
15
18
  end
16
19
  end
17
20
  end
18
- end
21
+ end
@@ -0,0 +1,34 @@
1
+ module Touchpass
2
+ module Rp
3
+ class Response
4
+
5
+ attr_accessor :http_status_code, :response
6
+
7
+ def initialize(http_party_response = nil)
8
+ if http_party_response
9
+ @http_status_code = http_party_response.code
10
+ @response = http_party_response.parsed_response
11
+ end
12
+ end
13
+
14
+ def to_h
15
+ if @response.kind_of?(Hash)
16
+ @response.merge(:http_status_code => @http_status_code)
17
+ elsif @http_status_code != 200
18
+ { :error => @response, :http_status_code => @http_status_code }
19
+ else
20
+ { :text => @response, :http_status_code => @http_status_code }
21
+ end
22
+ end
23
+
24
+ def [](key)
25
+ @response.kind_of?(Hash) ? @response[key] : nil
26
+ end
27
+
28
+ def to_json(options = {})
29
+ to_h.to_json(options)
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,53 @@
1
+ module Touchpass
2
+ module Rp
3
+ class Verification
4
+ include HTTParty
5
+ #debug_output
6
+
7
+ def initialize
8
+ self.class.base_uri Touchpass.base_uri
9
+ end
10
+
11
+ def create(to_party, options={})
12
+ http_options = { :body => { :to_party => to_party }, :headers => api_key_header }
13
+
14
+ # Defines which application will be used to handle the verification
15
+ # (the default is to use the standalone app, or the first app registered)
16
+ http_options[:body][:to_app_id] = Touchpass.app_id if Touchpass.app_id
17
+ # puts "Touchpass.app_id: #{Touchpass.app_id}"
18
+
19
+ # Get the verifying party devices so we can encrypt message/prp using the devices public key
20
+ device = Touchpass::Rp::Device.new
21
+ vp_devices = device.get_all(to_party).response
22
+ # TODO: vp_devices can be empty here, in which case verification creation will fail.
23
+
24
+ # Create verification object
25
+ verification = Touchpass::Verification.new(vp_devices, options)
26
+ http_options[:body].merge!(verification.http_params)
27
+
28
+ response = self.class.post("/verifications.json", http_options)
29
+
30
+ return Touchpass::Rp::Response.new(response)
31
+ end
32
+
33
+ def cancel(id)
34
+ http_options = { :body => {}, :headers => api_key_header }
35
+ response = self.class.put("/verifications/#{id}/cancel.json", http_options)
36
+ return Touchpass::Rp::Response.new(response)
37
+ end
38
+
39
+ def show(id)
40
+ http_options = { :body => {}, :headers => api_key_header }
41
+ response = self.class.get("/verifications/#{id}.json", http_options)
42
+ return Touchpass::Rp::Response.new(response)
43
+ end
44
+
45
+ private
46
+
47
+ def api_key_header
48
+ { Touchpass::Client::API_KEY_HEADER => Touchpass.api_key }
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -1,112 +1,145 @@
1
1
  module Touchpass
2
- module Rp
3
- class Verification
4
- include HTTParty
5
- #debug_output
2
+ class Verification
6
3
 
7
- def initialize
8
- self.class.base_uri Touchpass.base_uri
9
- end
10
-
11
- def create(to_party, options={})
12
- http_options = { :body => {:to_party => to_party}, :headers => api_key_header }
13
-
14
- # Get the verifying party devices so we can encrypt message/prp using the devices public key
15
- device = Touchpass::Rp::Device.new
16
- vp_devices = device.get_all(to_party)
17
-
18
- # Generate token
19
- token = Touchpass::Crypt.salt
20
- hashed_token = Touchpass::Crypt.encrypt(token)
21
- http_options[:body][:claimed_token] = hashed_token
22
-
23
- # Encrypt token using verifying_party (to_party) devices
24
- create_crypted_tokens(token, vp_devices, http_options)
25
-
26
- # Generate Claimed PRP (for Location Verification)
27
- create_prp(options[:address], vp_devices, http_options)
28
-
29
- # Generate Claimed PRP (for Location Verification)
30
- create_crypted_messages(options[:message], vp_devices, http_options)
4
+ attr_reader :crypted_salts, :crypted_tokens, :crypted_messages
5
+ attr_reader :claimed_token
6
+ attr_reader :location_verification, :claimed_prp, :resolution
31
7
 
32
- response = self.class.post("/verifications.json", http_options)
33
- return response.parsed_response
34
- end
35
-
36
- def cancel(id)
37
- http_options = { :body => {}, :headers => api_key_header }
38
- response = self.class.put("/verifications/#{id}/cancel.json", http_options)
39
- return response.parsed_response
8
+ def initialize(vp_devices, options = {})
9
+
10
+ # Generate token
11
+ token = Crypt.salt
12
+ hashed_token = Crypt.hash(token)
13
+ @claimed_token = hashed_token
14
+ @vp_devices = vp_devices
15
+ @crypted_messages = []
16
+
17
+ # Encrypt message using each verifying party's (to_party) device public keys
18
+ add_message(options[:message]) if !options[:message].nil?
19
+
20
+ # Encrypt post-verification message, if present
21
+ if !options[:message_post_verification].nil?
22
+ add_message(options[:message_post_verification],
23
+ :requires_verification => true,
24
+ :scratch_to_reveal => options[:scratch_to_reveal])
40
25
  end
41
26
 
42
- def show(id)
43
- http_options = { :body => {}, :headers => api_key_header }
44
- response = self.class.get("/verifications/#{id}.json", http_options)
45
- return response.parsed_response
27
+ # Encrypt post-verification location message, if present
28
+ if !options[:message_post_verification_location].nil?
29
+ add_message(options[:message_post_verification_location],
30
+ :requires_verification => true,
31
+ :requires_location_verification => true,
32
+ :scratch_to_reveal => options[:scratch_to_reveal])
46
33
  end
47
34
 
48
- private
49
- def create_crypted_tokens(token, devices, http_options)
50
- return if devices.nil? or (devices.is_a? Array and devices.empty?)
51
- devices.each_with_index do |device, index|
52
- device_id = device["id"]
53
- pub_key = device["pub_key"]
54
- public_key = Touchpass::Crypt.read_key(pub_key)
55
- crypted_token = Base64.encode64(public_key.public_encrypt(token))
56
- http_options[:body]["crypted_tokens[#{index}][device_id]"] = device_id
57
- http_options[:body]["crypted_tokens[#{index}][value]"] = crypted_token
58
- end
35
+ # allow adding messages from array of hashes (containing message and options)
36
+ messages = options[:messages]
37
+ messages = messages.values if messages.kind_of?(Hash)
38
+ if messages.kind_of?(Array)
39
+ messages.each { |i| add_message(i[:message], i) }
59
40
  end
60
41
 
61
- def create_prp(address, devices, http_options)
62
- return unless address.present?
42
+ # Encrypt token using each verifying party's (to_party) device public keys
43
+ # (only use RSA encryption for the token)
44
+ @crypted_tokens = crypted_values("crypted_tokens", token, :rsa_only => true)
63
45
 
64
- http_options[:body][:location_verification] = true
46
+ # Encrypt prp-hash using verifying_party (to_party) devices
47
+ if !options[:address].nil? # For location verification
48
+ @location_verification = true
65
49
 
66
- # Convert address to PRP
67
- http_options[:body][:resolution] = Touchpass.resolution # Resolution used to calculate PRP
68
- prp = Touchpass::Proximity::PRP.new(:address => address, :resolution => Touchpass.resolution)
50
+ # Convert address to PRP
51
+ @resolution = options[:resolution] || "LOCAL" # Resolution used to calculate PRP
52
+ prp = Proximity::PRP.new(:address => options[:address], :resolution => @resolution)
53
+ # puts prp.print_bbox # for debugging
69
54
 
70
55
  # Generate random salt
71
- salt = Touchpass::Crypt.salt
56
+ salt = Crypt.salt
57
+ # puts "Using salt: #{salt}" # for debugging
72
58
 
73
59
  # Encrypt PRP using salt
74
60
  claimed_prp = prp.encrypt(salt)
75
- http_options[:body][:claimed_prp] = claimed_prp
61
+ @claimed_prp = claimed_prp
76
62
 
77
63
  # Encrypt salt using verifiying_party (to_party) devices
78
- if !devices.nil? and (devices.is_a? Array and !devices.empty?)
79
- devices.each_with_index do |device, index|
80
- device_id = device["id"]
81
- pub_key = device["pub_key"]
82
- public_key = Touchpass::Crypt.read_key(pub_key)
83
- crypted_salt = Base64.encode64(public_key.public_encrypt(salt))
84
- http_options[:body]["crypted_salts[#{index}][device_id]"] = device_id
85
- http_options[:body]["crypted_salts[#{index}][value]"] = crypted_salt
86
- end
87
- end
64
+ @crypted_salts = crypted_values("crypted_salts", salt, :rsa_only => true)
88
65
  end
66
+
67
+ end
68
+
69
+ def add_message(message, options = {})
70
+ @crypted_messages ||= []
71
+ @crypted_messages += crypted_values("crypted_messages", message, options)
72
+ end
89
73
 
90
- def create_crypted_messages(message, devices, http_options)
91
- return if message.blank?
92
- return if devices.nil? or (devices.is_a? Array and devices.empty?)
93
-
94
- # Encrypt message using verifying party devices public key
95
- devices.each_with_index do |device, index|
96
- device_id = device["id"]
97
- pub_key = device["pub_key"]
98
- public_key = Touchpass::Crypt.read_key(pub_key)
99
- crypted_message = Base64.encode64(public_key.public_encrypt(message))
100
- http_options[:body]["crypted_messages[#{index}][device_id]"] = device_id
101
- http_options[:body]["crypted_messages[#{index}][value]"] = crypted_message
74
+ # create http parameters
75
+ def http_params
76
+ params = {}
77
+
78
+ params[:claimed_token] = @claimed_token
79
+ params[:crypted_messages] = param_hash(@crypted_messages)
80
+ params[:crypted_tokens] = param_hash(@crypted_tokens)
81
+ params[:crypted_salts] = param_hash(@crypted_salts)
82
+ params[:location_verification] = @location_verification
83
+ params[:resolution] = @resolution
84
+ params[:claimed_prp] = @claimed_prp
85
+
86
+ params
87
+ end
88
+
89
+ private
90
+
91
+ def param_hash(values)
92
+ ret = {}
93
+ if values.kind_of?(Array)
94
+ values.each_with_index do |value, i|
95
+ ret["#{i}"] = value
102
96
  end
103
97
  end
98
+ ret
99
+ end
100
+
101
+ # generate crypted value attributes for all devices
102
+ # used for messages and tokens
103
+ # returns array of hashes, hashes contain :device_id, :value, :key
104
+ def crypted_values(name, plaintext, options = {})
105
+ ret = []
106
+
107
+ return ret unless @vp_devices && @vp_devices.kind_of?(Array)
104
108
 
105
- private
106
- def api_key_header
107
- { Touchpass::Client::API_KEY_HEADER => Touchpass.api_key }
108
- end
109
+ @vp_devices.each do |device|
110
+ device_id = device["id"]
111
+
112
+ # get the RSA public key
113
+ pub_key_str = device["pub_key"]
114
+ next unless pub_key_str && pub_key_str.length > 0
115
+ public_key = Crypt.read_rsa_key(pub_key_str)
116
+
117
+ next unless public_key # skip invalid keys
118
+
119
+ if options[:rsa_only]
120
+ # encrypt plaintext using rsa
121
+ encrypted_data = public_key.public_encrypt(plaintext)
122
+ else
123
+ # encrypt using AES
124
+ # generate a random key, encrypt plaintext and key
125
+ key = Touchpass::Crypt.generate_encryption_key
126
+ encrypted_data = Touchpass::Crypt.encrypt(plaintext, key)
127
+ encrypted_key = public_key.public_encrypt(key)
128
+ end
109
129
 
130
+ # Note: some parts of the server code expect keys here to be strings (not symbols)
131
+ ret.push( {
132
+ "device_id" => device_id,
133
+ "value" => Base64.strict_encode64(encrypted_data),
134
+ "key" => encrypted_key ? Base64.strict_encode64(encrypted_key) : nil,
135
+ "requires_verification" => options[:requires_verification] ? true : false,
136
+ "requires_location_verification" => options[:requires_location_verification] ? true : false,
137
+ "scratch_to_reveal" => options[:scratch_to_reveal] ? true : false,
138
+ "do_not_keep" => options[:do_not_keep] ? true : false
139
+ })
140
+ end
141
+ ret
110
142
  end
143
+
111
144
  end
112
- end
145
+ end
@@ -1,3 +1,3 @@
1
1
  module Touchpass
2
- VERSION = "0.0.8.1"
2
+ VERSION = "0.0.8.16"
3
3
  end
data/lib/touchpass.rb CHANGED
@@ -1,16 +1,27 @@
1
1
  # -*- coding: utf-8 -*-
2
+
2
3
  require "touchpass/version"
3
4
  require 'touchpass/prp'
4
5
  require 'touchpass/client'
5
6
  require 'touchpass/crypt'
6
7
  require 'touchpass/key_file_creator'
7
8
  require 'touchpass/verification'
8
- require 'touchpass/device'
9
+ require 'touchpass/rp/response'
10
+ require 'touchpass/rp/verification'
11
+ require 'touchpass/rp/device'
9
12
 
10
13
  module Touchpass
11
- require 'engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
14
+ if defined?(Rails) && Rails::VERSION::MAJOR == 3
15
+ require 'engine'
16
+ class Engine < Rails::Engine
17
+ end
18
+ end
19
+
20
+ DEFAULT_HOST = "localhost"
21
+ DEFAULT_PORT = "3000"
22
+ DEFAULT_USE_HTTPS = true
12
23
 
13
- config = [:username, :api_key, :use_https, :host, :port, :resolution, :location_verification, :verified_message, :unverified_message]
24
+ config = [:username, :api_key, :use_https, :host, :port, :resolution, :location_verification, :verified_message, :unverified_message, :app_id]
14
25
 
15
26
  # define getter and setter methods for each config
16
27
  # normally we can use mattr_accessor :key for shortcut, but this only available in Rails environment
@@ -20,6 +31,13 @@ module Touchpass
20
31
  module_eval( "def self.#{symbol.to_s}=(val) @@#{symbol.to_s} = val; end" )
21
32
  end
22
33
 
34
+ begin
35
+ self.host = DEFAULT_HOST
36
+ self.port = DEFAULT_PORT
37
+ self.use_https = DEFAULT_USE_HTTPS
38
+ self.api_key = "" # prevents weird bug with HTTParty 'undefined method 'strip' for nil:NilClass'
39
+ end
40
+
23
41
  # Default way to setup Touchpass. Run rails generate touchpass_install to create
24
42
  # a fresh initializer with all configuration values.
25
43
  def self.setup
@@ -28,16 +46,20 @@ module Touchpass
28
46
 
29
47
  def self.base_uri
30
48
  tp_base_uri = Touchpass.host
31
- if Touchpass.port.present?
32
- tp_base_uri += ":#{Touchpass.port}"
49
+ port = Touchpass.port.to_s
50
+ unless port.empty? # .present? is a rails add-on
51
+ tp_base_uri += ":#{port}"
33
52
  end
34
53
  protocol = Touchpass.use_https ? "https://" : "http://"
35
54
  tp_base_uri = protocol + tp_base_uri
36
55
  end
37
56
 
38
57
  module Role
58
+ ADMIN = "admin"
39
59
  RELYING_PARTY = "relying_party"
40
60
  VERIFYING_PARTY = "verifying_party"
61
+
62
+ ROLES = [ADMIN, VERIFYING_PARTY, RELYING_PARTY]
41
63
  end
42
64
 
43
65
  module MessagingType