touchpass 0.0.8.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,256 @@
1
+ # Use BigDecimal for accuracy
2
+ require 'bigdecimal'
3
+ require 'geocoder'
4
+
5
+ begin
6
+ # TODO: use a disk cache?
7
+ Geocoder::Configuration.cache = {}
8
+ end
9
+
10
+ module Touchpass
11
+ module Proximity
12
+ # PRP - Privacy Respecting Proximity
13
+ # Provides mechanisms that allows locations to be compared
14
+ # for proximity without revealing the actual location of
15
+ # either party.
16
+ class PRP
17
+
18
+ class BBoxResolution
19
+ # Bounding box resolutions:
20
+ STREET = 0.001 # 3 decimal places
21
+ LOCAL = 0.01 # 2 decimal places
22
+ METRO = 0.1 # 1 decimal place
23
+ REGIONAL = 1 # 0 decimal places
24
+ end
25
+
26
+ # Minumum and maximum value for latitude
27
+ MIN_LAT, MAX_LAT = BigDecimal.new("-90.0"), BigDecimal.new("90.0")
28
+ # Minumum and maximum value for longitude
29
+ MIN_LNG, MAX_LNG = BigDecimal.new("-180.0"), BigDecimal.new("180.0")
30
+
31
+ attr_reader :lat, :lng, :resolution
32
+ attr_reader :bounding_coordinates
33
+ attr :crypted_coordinates
34
+
35
+ # Given a coordinate (latitude and longitude) and an Bounding Box resolution, return a PRP geohash
36
+ def initialize(params={})
37
+ resolution = params[:resolution]
38
+ if resolution.nil? or resolution == ""
39
+ resolution = 'LOCAL'
40
+ end
41
+
42
+ if params.has_key? :lat and params.has_key? :lng
43
+ @lat, @lng = lat, lng
44
+ elsif params[:address]
45
+ addr = nil
46
+ if params[:address].is_a? String
47
+ addr = params[:address]
48
+ elsif params[:address].is_a? Hash
49
+ addr = build_address(params[:address])
50
+ end
51
+
52
+ coord = Geocoder.coordinates(addr) if addr
53
+ #puts "addr = #{addr}"
54
+ #puts "coord = #{coord.first}, #{coord.last}"
55
+ return false if coord.nil? # Should we raise exception here?
56
+ @lat, @lng = coord.first, coord.last
57
+ end
58
+
59
+ case resolution.upcase
60
+ when 'STREET'
61
+ @resolution = BBoxResolution::STREET
62
+ when 'LOCAL'
63
+ @resolution = BBoxResolution::LOCAL
64
+ when 'METRO'
65
+ @resolution = BBoxResolution::METRO
66
+ when 'REGIONAL'
67
+ @resolution = BBoxResolution::REGIONAL
68
+ else
69
+ raise Exception, "Unknown resolution '#{resolution}'."
70
+ end
71
+
72
+ # convert lat, lng to bigdecimal
73
+ @lat, @lng = BigDecimal.new(@lat.to_s), BigDecimal.new(@lng.to_s)
74
+
75
+ # calculate bounding coordinates
76
+ calculate_bounding_coordinates!(@resolution)
77
+ end
78
+
79
+ # Calculates four coordinates that represent an anonymised version of the location.
80
+ # Anonymised means that regardless of the absolute value of lat and lng, the four
81
+ # coordinates will be a bounding box around the point.
82
+ # Returns an array of lat/lng coordinates that bound the coordinates.
83
+ # Notes:
84
+ # Size of the bounding box is determined by the granularity parameter
85
+ def calculate_bounding_coordinates!(resolution)
86
+ return @bounding_coordinates unless @bounding_coordinates.nil?
87
+
88
+ trunc = Touchpass::Proximity::PRP.truncate_size(resolution)
89
+ granularity = BigDecimal.new(resolution.to_s)
90
+
91
+ min_lat = @lat.truncate(trunc)
92
+ min_lng = @lng.truncate(trunc)
93
+
94
+ # Allow for different calcs depending on sign of lat and lng
95
+ if @lat > 0.0
96
+ max_lat = min_lat + granularity
97
+ else
98
+ max_lat = min_lat
99
+ min_lat = max_lat - granularity
100
+ end
101
+ if @lng > 0.0
102
+ max_lng = min_lng + granularity
103
+ else
104
+ max_lng = min_lng
105
+ min_lng = max_lng - granularity
106
+ end
107
+
108
+ @bounding_coordinates = {
109
+ :top_left => [max_lat, min_lng],
110
+ :top_right => [max_lat, max_lng],
111
+ :bottom_right => [min_lat, max_lng],
112
+ :bottom_left => [min_lat, min_lng]
113
+ }
114
+
115
+ # Calibrate lats and lngs
116
+ @bounding_coordinates.collect{|k, coords| coords[0] = Touchpass::Proximity::PRP.calibrate_lat(coords[0])}
117
+ @bounding_coordinates.collect{|k, coords| coords[1] = Touchpass::Proximity::PRP.calibrate_lng(coords[1])}
118
+
119
+ return @bounding_coordinates
120
+ end
121
+
122
+ # Returns the bounding coordinates
123
+ def bounding_box
124
+ return @bounding_coordinates
125
+ end
126
+
127
+ def calibrated?
128
+ return false if @bounding_coordinates.nil? or @bounding_coordinates.empty?
129
+ for key in [:top_left, :top_right, :bottom_right, :bottom_left]
130
+ return false if !@bounding_coordinates.has_key?(key)
131
+ end
132
+ return true
133
+ end
134
+
135
+ # Test to see if the specified location is near this one, where
136
+ # 'near' means at least one of its bounding coordinates is shared between the two points
137
+ def proximate?(other_prp)
138
+ return Touchpass::Proximity::PRP.proximate?(self, other_prp)
139
+ end
140
+
141
+ def common_bounding_coordinates(other_prp)
142
+ return Touchpass::Proximity::PRP.common_bounding_coordinates(self, other_prp)
143
+ end
144
+
145
+ # Returns the hashed representation of the bounding coordinates
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
152
+ return @crypted_coordinates
153
+ end
154
+
155
+ def encrypt_point(point=[], salt=nil)
156
+ return if point.size!=2
157
+
158
+ # Format lat, lng with correct decimal places
159
+ # STREET : 3 decimal places (e.g. -33.860, 151.200)
160
+ # LOCAL : 2 decimal places (e.g. -33.86, 151.20)
161
+ # METRO : 1 decimal places (e.g. -33.8, 151.2)
162
+ # REGIONAL: 0 decimal places (e.g. -33, 151)
163
+ lat = Touchpass::Proximity::PRP.format_decimal(point.first, Touchpass::Proximity::PRP.truncate_size(@resolution))
164
+ lng = Touchpass::Proximity::PRP.format_decimal(point.last, Touchpass::Proximity::PRP.truncate_size(@resolution))
165
+
166
+ # MFS: 20100722
167
+ # Original approach hashed points in the corner independently. eg:
168
+ # return crypto_provider.hexdigest(lat.to_s) + crypto_provider.hexdigest(lng.to_s)
169
+ # Changed to string concat the points together *before* the hash so that we end up with hash values
170
+ # 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
+ # possible values.
172
+ str_to_encrypt = (lat.to_s) + "," + (lng.to_s) + salt.to_s
173
+ return Touchpass::Crypt.encrypt(str_to_encrypt)
174
+ end
175
+
176
+ def self.truncate_size(resolution)
177
+ split = resolution.to_s.split(".")
178
+ return split.size==1 ? 0 : split.last.size
179
+ end
180
+
181
+ # Truncate decimal (not round)
182
+ # E.g.
183
+ # format_decimal(-33.860987, 3) #=> -33.860
184
+ # format_decimal(-33.860987, 2) #=> -33.86
185
+ # format_decimal(-33.860987, 1) #=> -33.8
186
+ # format_decimal(-33.860987, 0) #=> -33
187
+ # format_decimal(151.200948, 3) #=> 151.200
188
+ # format_decimal(151.200948, 2) #=> 151.20
189
+ # format_decimal(151.200948, 1) #=> 151.2
190
+ # format_decimal(151.200948, 0) #=> 151
191
+ def self.format_decimal(decimal, decimal_places)
192
+ # KM: 20110927
193
+ # Original approach was to round decimal. eg:
194
+ # {}"%.#{decimal_places}f" % decimal
195
+ # Changed to truncate without rounding
196
+ t = 10.0 ** decimal_places
197
+ "%.#{decimal_places}f" % ((decimal * t).truncate / t)
198
+ end
199
+
200
+ def self.calibrate_lat(lat)
201
+ if lat == 0.0
202
+ # make sure -0.0 turned into 0.0
203
+ lat = BigDecimal("0.0")
204
+ elsif !(MIN_LAT..MAX_LAT).include?(lat)
205
+ # latitude must fall within its range
206
+ lat = (lat<MIN_LAT) ? MIN_LAT : MAX_LAT
207
+ end
208
+ return lat
209
+ end
210
+
211
+ def self.calibrate_lng(lng)
212
+ if lng == 0.0
213
+ # make sure -0.0 turned into 0.0
214
+ lng = BigDecimal("0.0")
215
+ elsif !(MIN_LNG..MAX_LNG).include?(lng)
216
+ # longitude must fall within its range
217
+ lng = (lng<MIN_LNG) ? MIN_LNG : MAX_LNG
218
+ end
219
+ return lng
220
+ end
221
+
222
+ def self.proximate?(prp, other_prp)
223
+ return !Touchpass::Proximity::PRP.common_bounding_coordinates(prp, other_prp).empty?
224
+ end
225
+
226
+ def self.common_bounding_coordinates(prp, other_prp)
227
+ return nil unless prp.bounding_coordinates
228
+ bounding_coords_1 = prp.bounding_coordinates.collect{|k, v| v}
229
+ bounding_coords_2 = other_prp.bounding_coordinates.collect{|k, v| v}
230
+ return bounding_coords_1 & bounding_coords_2
231
+ end
232
+
233
+ def print_bbox
234
+ for point in [:top_left, :top_right, :bottom_right, :bottom_left]
235
+ lat = Touchpass::Proximity::PRP.format_decimal(self.bounding_coordinates[point].first, Touchpass::Proximity::PRP.truncate_size(@resolution))
236
+ lng = Touchpass::Proximity::PRP.format_decimal(self.bounding_coordinates[point].last, Touchpass::Proximity::PRP.truncate_size(@resolution))
237
+ # lat = "%.#{Touchpass::Proximity::PRP.truncate_size(@resolution)}f" % self.bounding_coordinates[point].first
238
+ # lng = "%.#{Touchpass::Proximity::PRP.truncate_size(@resolution)}f" % self.bounding_coordinates[point].last
239
+ puts "#{point.to_s}: [#{lat.to_s}, #{lng.to_s}]"
240
+ end
241
+ return true
242
+ end
243
+
244
+ # Converts addresss Hash to String
245
+ # "120 Sussex Street, Sydney 2000, NSW Australia"
246
+ def build_address(attributes)
247
+ address = attributes[:address] + ","
248
+ address << " #{attributes[:city]}" if attributes[:city].present?
249
+ address << " #{attributes[:postcode]}" if attributes[:postcode].present?
250
+ address << ", #{attributes[:state]}" if attributes[:state].present?
251
+ address << " #{attributes[:country]}" if attributes[:country].present?
252
+ address
253
+ end
254
+ end
255
+ end
256
+ end
@@ -0,0 +1,112 @@
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
+ # 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)
31
+
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
40
+ end
41
+
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
46
+ end
47
+
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
59
+ end
60
+
61
+ def create_prp(address, devices, http_options)
62
+ return unless address.present?
63
+
64
+ http_options[:body][:location_verification] = true
65
+
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)
69
+
70
+ # Generate random salt
71
+ salt = Touchpass::Crypt.salt
72
+
73
+ # Encrypt PRP using salt
74
+ claimed_prp = prp.encrypt(salt)
75
+ http_options[:body][:claimed_prp] = claimed_prp
76
+
77
+ # 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
88
+ end
89
+
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
102
+ end
103
+ end
104
+
105
+ private
106
+ def api_key_header
107
+ { Touchpass::Client::API_KEY_HEADER => Touchpass.api_key }
108
+ end
109
+
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,3 @@
1
+ module Touchpass
2
+ VERSION = "0.0.8.1"
3
+ end
data/lib/touchpass.rb ADDED
@@ -0,0 +1,53 @@
1
+ # -*- coding: utf-8 -*-
2
+ require "touchpass/version"
3
+ require 'touchpass/prp'
4
+ require 'touchpass/client'
5
+ require 'touchpass/crypt'
6
+ require 'touchpass/key_file_creator'
7
+ require 'touchpass/verification'
8
+ require 'touchpass/device'
9
+
10
+ module Touchpass
11
+ require 'engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
12
+
13
+ config = [:username, :api_key, :use_https, :host, :port, :resolution, :location_verification, :verified_message, :unverified_message]
14
+
15
+ # define getter and setter methods for each config
16
+ # normally we can use mattr_accessor :key for shortcut, but this only available in Rails environment
17
+ config.each do |symbol|
18
+ eval("@@#{symbol.to_s} = nil")
19
+ module_eval( "def self.#{symbol.to_s}() @@#{symbol.to_s}; end" )
20
+ module_eval( "def self.#{symbol.to_s}=(val) @@#{symbol.to_s} = val; end" )
21
+ end
22
+
23
+ # Default way to setup Touchpass. Run rails generate touchpass_install to create
24
+ # a fresh initializer with all configuration values.
25
+ def self.setup
26
+ yield self
27
+ end
28
+
29
+ def self.base_uri
30
+ tp_base_uri = Touchpass.host
31
+ if Touchpass.port.present?
32
+ tp_base_uri += ":#{Touchpass.port}"
33
+ end
34
+ protocol = Touchpass.use_https ? "https://" : "http://"
35
+ tp_base_uri = protocol + tp_base_uri
36
+ end
37
+
38
+ module Role
39
+ RELYING_PARTY = "relying_party"
40
+ VERIFYING_PARTY = "verifying_party"
41
+ end
42
+
43
+ module MessagingType
44
+ APN = "apn"
45
+ APN_DEV = "apn-development"
46
+ #SMS = "sms" # not supported yet
47
+
48
+ def self.all
49
+ [APN, APN_DEV]
50
+ end
51
+ end
52
+
53
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Bounding Box" do
4
+
5
+ context "using north of equator" do
6
+ it "should have 4 points (top_left, top_right, bottom_right, bottom_left)" do
7
+ prp = Touchpass::Proximity::PRP.new(north_of_equator)
8
+ prp.bounding_box.size.should eql(4)
9
+ for point in [:top_left, :top_right, :bottom_right, :bottom_left]
10
+ prp.bounding_box[point].should be
11
+ end
12
+ end
13
+ end
14
+
15
+ context "using orbitec office in sydney" do
16
+ it "should have 4 points (top_left, top_right, bottom_right, bottom_left)" do
17
+ Geocoder.should_receive(:coordinates).and_return([1, 2]) # dummy values
18
+
19
+ prp = Touchpass::Proximity::PRP.new(:address => orbitec_office)
20
+ prp.bounding_box.size.should eql(4)
21
+ for point in [:top_left, :top_right, :bottom_right, :bottom_left]
22
+ prp.bounding_box[point].should be
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Geocode" do
4
+
5
+ for address in addresses
6
+
7
+ it "should find geographic coordinates for address '#{address}'" do
8
+ dummy_lat = 10
9
+ dummy_lon = 11
10
+
11
+ # avoid hammering the geocode server
12
+ # (we just want to test Touchpass::Proximity::PRP, rather than Geocoder)
13
+ Geocoder.should_receive(:coordinates).and_return([dummy_lat, dummy_lon])
14
+
15
+ prp = Touchpass::Proximity::PRP.new(:address => address)
16
+ prp.lat.should == dummy_lat
17
+ prp.lng.should == dummy_lon
18
+ end
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1 @@
1
+ require 'touchpass'
@@ -0,0 +1,98 @@
1
+ require 'touchpass'
2
+
3
+ def orbitec_office
4
+ '120 Sussex St Sydney NSW 2000 Australia'
5
+ end
6
+
7
+ def apple_store_sydney
8
+ '367 George Street Sydney 2000 NSW Australia'
9
+ end
10
+
11
+ def mecca_espresso_king_st
12
+ '67 King Street Sydney 2000 NSW Australia'
13
+ end
14
+
15
+ def talga_rd_rothbury
16
+ '127 Talga Rd Rothbury NSW 2320 Australia'
17
+ end
18
+
19
+ def cessnock_post_office
20
+ '16/205 Wollombi Rd Cessnock NSW 2325 Australia'
21
+ end
22
+
23
+ def holdsworth_st_neutralbay
24
+ '2/10 Holdsworth St Neutral Bay New South Wales 2089'
25
+ end
26
+
27
+ def north_sydney_post_office
28
+ '92 Pacific Highway North Sydney NSW 2060 Australia'
29
+ end
30
+
31
+ def empire_state_building
32
+ '350 5th Avenue New York, NY 10118-3304, United States'
33
+ end
34
+
35
+ def chrysler_building
36
+ 'Chrysler Building, New York, NY, United States'
37
+ end
38
+
39
+ def themet
40
+ 'Metropolitan Museum of Art 5th Avenue New York NY United States'
41
+ end
42
+
43
+ def addresses
44
+ [orbitec_office, apple_store_sydney, mecca_espresso_king_st, talga_rd_rothbury, cessnock_post_office, holdsworth_st_neutralbay, north_sydney_post_office,
45
+ empire_state_building, chrysler_building, themet]
46
+ end
47
+
48
+ def resolutions
49
+ ['street', 'local', 'metro', 'regional']
50
+ end
51
+
52
+ def north_of_equator
53
+ { :lat => 0.0525, :lng => 151.2348 }
54
+ end
55
+
56
+ def south_of_equator
57
+ { :lat => -0.0525, :lng => 151.2348 }
58
+ end
59
+
60
+ def east_of_gmt
61
+ { :lat => 33.8, :lng => 0.0525 }
62
+ end
63
+
64
+ def west_of_gmt
65
+ { :lat => 33.8, :lng => -0.0525 }
66
+ end
67
+
68
+ def north_west_of_equator_and_gmt
69
+ { :lat => 0.0525, :lng => -0.0525 }
70
+ end
71
+
72
+ def north_east_of_equator_and_gmt
73
+ { :lat => 0.0525, :lng => 0.0525 }
74
+ end
75
+
76
+ def south_east_of_equator_and_gmt
77
+ { :lat => -0.0525, :lng => 0.0525 }
78
+ end
79
+
80
+ def south_west_of_equator_and_gmt
81
+ { :lat => -0.0525, :lng => -0.0525 }
82
+ end
83
+
84
+ def cornercase1
85
+ { :lat => -0.15, :lng => -0.15 }
86
+ end
87
+
88
+ def cornercase2
89
+ { :lat => 0.15, :lng => 0.15 }
90
+ end
91
+
92
+ def cornercase3
93
+ { :lat => 0.15, :lng => -0.15 }
94
+ end
95
+
96
+ def cornercase4
97
+ { :lat => -0.15, :lng => 0.15 }
98
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Key File Creator" do
4
+
5
+ context "create public / private keys" do
6
+
7
+ before do
8
+ @device_id = "1"
9
+ @device_udid = "747c37dc35b66830e921148398e77f3b3f5e2c3b"
10
+ @key_file_helper = Touchpass::KeyFileCreator.new(@device_id)
11
+ end
12
+
13
+ it "should initialise" do
14
+ @key_file_helper.should be
15
+ end
16
+
17
+ it "should create public and private key files" do
18
+ @key_file_helper.generate_keys
19
+
20
+ # Read in the public and private keys from the generated files
21
+ expected_public_key = OpenSSL::PKey::RSA.new(File.read(File.join(Touchpass::KeyFileCreator.keys_path, @device_id, Touchpass::KeyFileCreator::PUBLIC_KEY))).to_s
22
+ expected_private_key = OpenSSL::PKey::RSA.new(File.read(File.join(Touchpass::KeyFileCreator.keys_path, @device_id, Touchpass::KeyFileCreator::PRIVATE_KEY))).to_s
23
+
24
+ @key_file_helper.public_key.to_s.should == expected_public_key
25
+ @key_file_helper.private_key.to_s.should == expected_private_key
26
+ end
27
+
28
+ end
29
+
30
+ end