touchpass 0.0.8.1 → 0.0.8.16

Sign up to get free protection for your applications and to get access to all the features.
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