u2f 0.0.2 → 0.0.3
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 +4 -4
- data/lib/u2f/collection.rb +2 -0
- data/lib/u2f/register_response.rb +12 -43
- data/lib/u2f/u2f.rb +65 -3
- data/lib/version.rb +1 -1
- data/spec/lib/register_response_spec.rb +3 -3
- data/spec/lib/u2f_spec.rb +4 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c779dd25f9a95cfc831617c40bd58adc467a36eb
|
4
|
+
data.tar.gz: 94efeeaad1dacd2f0d77a9c78732643d91b750db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec901166a6ae4436cad602d63016e392f10a0d2deaa78f20ea4ec0555e9e8f16bb65af5508ecc04e3928fb91a989b993341c77d469f5bfdadd725b8c48501219
|
7
|
+
data.tar.gz: 0d48814191c242bc0f5cec5ece404d5e85cb321cc110db2e767156763255a54322dc242bae9a1200a87503314d5d39180597b50a96f71ece49209b30b8861795
|
data/lib/u2f/collection.rb
CHANGED
@@ -28,55 +28,25 @@ module U2F
|
|
28
28
|
##
|
29
29
|
# The attestation certificate in Base64 encoded X.509 DER format
|
30
30
|
def certificate
|
31
|
-
Base64.strict_encode64(
|
31
|
+
Base64.strict_encode64(parsed_certificate.to_der)
|
32
32
|
end
|
33
33
|
|
34
34
|
##
|
35
|
-
#
|
36
|
-
def
|
37
|
-
|
38
|
-
#
|
39
|
-
# Do some quick parsing of the certificate DER format.
|
40
|
-
# First bytes (TLV) could be ex:
|
41
|
-
# T 0x30: SEQUENCE Tag
|
42
|
-
# L 0x82: Length (2 length bytes)
|
43
|
-
# 0x02 0xe2: Two bytes indicated by the L byte.
|
44
|
-
# Makes up the data length 738 (which makes 742 in total)
|
45
|
-
|
46
|
-
t_byte = certificate_bytes(0)
|
47
|
-
|
48
|
-
fail AttestationDecodeError unless t_byte == "\x30"
|
49
|
-
|
50
|
-
l_byte = certificate_bytes(1).unpack('c').first # 8-bit signed integer
|
51
|
-
# If the L-byte has MSB set to 1 (ie. < 0) the value will tell how many
|
52
|
-
# following bytes is used to describe the total length. Otherwise it will
|
53
|
-
# describe the data length
|
54
|
-
# http://msdn.microsoft.com/en-us/library/windows/desktop/bb648641(v=vs.85).aspx
|
55
|
-
|
56
|
-
nbr_length_bytes = 0
|
57
|
-
cert_length = if l_byte < 0
|
58
|
-
nbr_length_bytes = l_byte + 0x80 # last 7-bits is the number of bytes
|
59
|
-
length_bytes = certificate_bytes(2, nbr_length_bytes).unpack('C*')
|
60
|
-
length_bytes.reverse.each_with_index.inject(0) do |sum, (val, idx)|
|
61
|
-
sum + (val << (8*idx))
|
62
|
-
end
|
63
|
-
else
|
64
|
-
l_byte
|
65
|
-
end
|
66
|
-
|
67
|
-
cert_length + nbr_length_bytes + 2 # Make up for the T and L bytes them selves
|
35
|
+
# The parsed attestation certificate
|
36
|
+
def parsed_certificate
|
37
|
+
OpenSSL::X509::Certificate.new(certificate_bytes)
|
68
38
|
end
|
69
39
|
|
70
40
|
##
|
71
|
-
#
|
72
|
-
def
|
73
|
-
|
41
|
+
# Length of the attestation certificate
|
42
|
+
def certificate_length
|
43
|
+
parsed_certificate.to_der.bytesize
|
74
44
|
end
|
75
45
|
|
76
46
|
##
|
77
47
|
# Returns the key handle from registration data, URL safe base64 encoded
|
78
48
|
def key_handle
|
79
|
-
|
49
|
+
::U2F.urlsafe_encode64(key_handle_raw)
|
80
50
|
end
|
81
51
|
|
82
52
|
def key_handle_raw
|
@@ -108,7 +78,7 @@ module U2F
|
|
108
78
|
end
|
109
79
|
|
110
80
|
##
|
111
|
-
# Verifies the registration data
|
81
|
+
# Verifies the registration data against the app id
|
112
82
|
def verify(app_id)
|
113
83
|
# Chapter 4.3 in
|
114
84
|
# http://fidoalliance.org/specs/fido-u2f-raw-message-formats-v1.0-rd-20141008.pdf
|
@@ -120,15 +90,14 @@ module U2F
|
|
120
90
|
public_key_raw
|
121
91
|
].join
|
122
92
|
|
123
|
-
|
124
|
-
cert.public_key.verify(OpenSSL::Digest::SHA256.new, signature, data)
|
93
|
+
parsed_certificate.public_key.verify(OpenSSL::Digest::SHA256.new, signature, data)
|
125
94
|
end
|
126
95
|
|
127
96
|
private
|
128
97
|
|
129
|
-
def certificate_bytes
|
98
|
+
def certificate_bytes
|
130
99
|
base_offset = KEY_HANDLE_OFFSET + key_handle_length
|
131
|
-
registration_data_raw.byteslice(base_offset
|
100
|
+
registration_data_raw.byteslice(base_offset..-1)
|
132
101
|
end
|
133
102
|
end
|
134
103
|
end
|
data/lib/u2f/u2f.rb
CHANGED
@@ -1,12 +1,23 @@
|
|
1
1
|
module U2F
|
2
2
|
class U2F
|
3
3
|
attr_accessor :app_id
|
4
|
+
##
|
5
|
+
# * *Args*:
|
6
|
+
# - +app_id+:: An application (facet) ID string
|
7
|
+
#
|
4
8
|
def initialize(app_id)
|
5
9
|
@app_id = app_id
|
6
10
|
end
|
7
11
|
|
8
12
|
##
|
9
13
|
# Generate data to be sent to the U2F device before authenticating
|
14
|
+
#
|
15
|
+
# * *Args*:
|
16
|
+
# - +key_handles+:: +Array+ of previously registered U2F key handles
|
17
|
+
#
|
18
|
+
# * *Returns*:
|
19
|
+
# - A +Collection+ of +SignRequest+ objects
|
20
|
+
#
|
10
21
|
def authentication_requests(key_handles)
|
11
22
|
key_handles = [key_handles] unless key_handles.is_a? Array
|
12
23
|
sign_requests = key_handles.map do |key_handle|
|
@@ -17,6 +28,20 @@ module U2F
|
|
17
28
|
|
18
29
|
##
|
19
30
|
# Authenticate a response from the U2F device
|
31
|
+
#
|
32
|
+
# * *Args*:
|
33
|
+
# - +challenges+:: +Array+ of challenge strings
|
34
|
+
# - +response+:: Response from the U2F device as a +SignResponse+ object
|
35
|
+
# - +registration_public_key+:: Public key of the registered U2F device as binary string
|
36
|
+
# - +registration_counter+:: +Integer+ with the current counter value of the registered device.
|
37
|
+
#
|
38
|
+
# * *Raises*:
|
39
|
+
# - +NoMatchingRequestError+:: if the challenge in the response doesn't match any of the provided ones.
|
40
|
+
# - +ClientDataTypeError+:: if the response is of the wrong type
|
41
|
+
# - +AuthenticationFailedError+:: if the authentication failed
|
42
|
+
# - +UserNotPresentError+:: if the user wasn't present during the authentication
|
43
|
+
# - +CounterToLowError+:: if there is a counter mismatch between the registered one and the one in the response.
|
44
|
+
#
|
20
45
|
def authenticate!(challenges, response, registration_public_key,
|
21
46
|
registration_counter)
|
22
47
|
# Handle both single and Array input
|
@@ -42,12 +67,20 @@ module U2F
|
|
42
67
|
|
43
68
|
##
|
44
69
|
# Generates a 32 byte long random U2F challenge
|
70
|
+
#
|
71
|
+
# * *Returns*:
|
72
|
+
# - Base64 urlsafe encoded challenge
|
73
|
+
#
|
45
74
|
def challenge
|
46
|
-
|
75
|
+
::U2F.urlsafe_encode64(SecureRandom.random_bytes(32))
|
47
76
|
end
|
48
77
|
|
49
78
|
##
|
50
79
|
# Generate data to be used when registering a U2F device
|
80
|
+
#
|
81
|
+
# * *Returns*:
|
82
|
+
# - A +Collection+ of +RegisterRequest+ objects
|
83
|
+
#
|
51
84
|
def registration_requests
|
52
85
|
# TODO: generate a request for each supported version
|
53
86
|
Collection.new(RegisterRequest.new(challenge, @app_id))
|
@@ -55,7 +88,19 @@ module U2F
|
|
55
88
|
|
56
89
|
##
|
57
90
|
# Authenticate the response from the U2F device when registering
|
58
|
-
#
|
91
|
+
#
|
92
|
+
# * *Args*:
|
93
|
+
# - +challenges+:: +Array+ of challenge strings
|
94
|
+
# - +response+:: Response of the U2F device as a +RegisterResponse+ object
|
95
|
+
#
|
96
|
+
# * *Returns*:
|
97
|
+
# - A +Registration+ object
|
98
|
+
#
|
99
|
+
# * *Raises*:
|
100
|
+
# - +UnmatchedChallengeError+:: if the challenge in the response doesn't match any of the provided ones.
|
101
|
+
# - +ClientDataTypeError+:: if the response is of the wrong type
|
102
|
+
# - +AttestationSignatureError+:: if the registration failed
|
103
|
+
#
|
59
104
|
def register!(challenges, response)
|
60
105
|
challenges = [challenges] unless challenges.is_a? Array
|
61
106
|
challenge = challenges.detect do |chg|
|
@@ -86,6 +131,15 @@ module U2F
|
|
86
131
|
|
87
132
|
##
|
88
133
|
# Convert a binary public key to PEM format
|
134
|
+
# * *Args*:
|
135
|
+
# - +key+:: Binary public key
|
136
|
+
#
|
137
|
+
# * *Returns*:
|
138
|
+
# - A base64 encoded public key +String+ in PEM format
|
139
|
+
#
|
140
|
+
# * *Raises*:
|
141
|
+
# - +PublicKeyDecodeError+:: if the +key+ argument is incorrect
|
142
|
+
#
|
89
143
|
def self.public_key_pem(key)
|
90
144
|
fail PublicKeyDecodeError unless key.length == 65 || key[0] == "\x04"
|
91
145
|
# http://tools.ietf.org/html/rfc5480
|
@@ -112,7 +166,8 @@ module U2F
|
|
112
166
|
end
|
113
167
|
|
114
168
|
##
|
115
|
-
# Variant of Base64::
|
169
|
+
# Variant of Base64::urlsafe_decode64 which adds padding if necessary
|
170
|
+
#
|
116
171
|
def self.urlsafe_decode64(string)
|
117
172
|
string = case string.length % 4
|
118
173
|
when 2 then string + '=='
|
@@ -122,4 +177,11 @@ module U2F
|
|
122
177
|
end
|
123
178
|
Base64.urlsafe_decode64(string)
|
124
179
|
end
|
180
|
+
|
181
|
+
##
|
182
|
+
# Variant of Base64::urlsafe_encode64 which removes padding
|
183
|
+
#
|
184
|
+
def self.urlsafe_encode64(string)
|
185
|
+
Base64.urlsafe_encode64(string).delete('=')
|
186
|
+
end
|
125
187
|
end
|
data/lib/version.rb
CHANGED
@@ -2,7 +2,7 @@ require 'spec_helper.rb'
|
|
2
2
|
|
3
3
|
describe U2F::RegisterResponse do
|
4
4
|
let(:key_handle) do
|
5
|
-
'CTUayZo8hCBeC-sGQJChC0wW-bBg99bmOlGCgw8XGq4dLsxO3yWh9mRYArZxocP5hBB1pEGB3bbJYiM-5acc5w
|
5
|
+
'CTUayZo8hCBeC-sGQJChC0wW-bBg99bmOlGCgw8XGq4dLsxO3yWh9mRYArZxocP5hBB1pEGB3bbJYiM-5acc5w'
|
6
6
|
end
|
7
7
|
let(:public_key) do
|
8
8
|
'BC0SaFZWC9uH7wamOwduP93kUH2I2hEvyY0Srfj4A258pZSlV0iPoFIH+bd4yhncaqdoPLdEDl5Y/yaFORPUe3c='
|
@@ -11,11 +11,11 @@ describe U2F::RegisterResponse do
|
|
11
11
|
'MIIC4jCBywIBATANBgkqhkiG9w0BAQsFADAdMRswGQYDVQQDExJZdWJpY28gVTJGIFRlc3QgQ0EwHhcNMTQwNTE1MTI1ODU0WhcNMTQwNjE0MTI1ODU0WjAdMRswGQYDVQQDExJZdWJpY28gVTJGIFRlc3QgRUUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATbCtv1IcdczmPcpuHoJQYNlOYnVBlPnSSvJhq+rZlEH5WjcZEKOiDnPpFeE+i+OAV61XqjfnaQj6/iipS2MOudMA0GCSqGSIb3DQEBCwUAA4ICAQCVQGtQYX2thKO064gP4zAPLaIKANklBO5y+mffWFEPC0cCnD5BKUqTrCmFiS2keoEyKFdxAe+oQogWljeR1d/gj8k8jbDNiXCC7HnTxnhzKTLlq2y9Vp/VRZHOwd2NZNzpnB9ePNKvUaWCGK/gN+cynnYFdwJ75iSgMVYb/RnFcdPwnsBzBU68hbhTnu/FvJxWo7rZJ2q7qXpA10eLVXJr4/4oSXEk9I/0IIHqOP98Ck/fAoI5gYI7ygndyqoPJ/Wkg1VsmjmbFToWY9xb+axbvPefvg+KojwxE6MySMpYh/h7oKEKamCWk19dJp5jHQmumkHlvQhH/uUJmyD9EuLmQH+6SmEzZg0Oc9uw1aKamhcNNDCFakJGnv80j1+HbDXnqE0168FBqorS2hmqeaJfNSyg/SXT950lGC36tLy7BzQ8jYG99Ok32znp0UVbIEEvLSci3JJ0ipLVg/0J+xOb4zl6a1z65nae4OTj7628/UJFmtSU0X6Np9gF1dNizxXPlH0fW1ggRCCQcb5m6ZqrdDJwUx1p7Ydm9AlPyiUwwmN5ADyxmzk/AOCoiO96UVvnvUlk2kF7JMNxIv3R0SCzP5fTl7KqGByeA3d7W375o6DWIIEsOI+dJd7pyPXdakecZQRaVubC6/ICl+G52OEkdp8jYjkDS8j3NAdJ1udNmg=='
|
12
12
|
end
|
13
13
|
let(:registration_data_json) do
|
14
|
-
'{ "registrationData": "BQQtEmhWVgvbh-8GpjsHbj_d5FB9iNoRL8mNEq34-ANufKWUpVdIj6BSB_m3eMoZ3GqnaDy3RA5eWP8mhTkT1Ht3QAk1GsmaPIQgXgvrBkCQoQtMFvmwYPfW5jpRgoMPFxquHS7MTt8lofZkWAK2caHD-YQQdaRBgd22yWIjPuWnHOcwggLiMIHLAgEBMA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNVBAMTEll1YmljbyBVMkYgVGVzdCBDQTAeFw0xNDA1MTUxMjU4NTRaFw0xNDA2MTQxMjU4NTRaMB0xGzAZBgNVBAMTEll1YmljbyBVMkYgVGVzdCBFRTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABNsK2_Uhx1zOY9ym4eglBg2U5idUGU-dJK8mGr6tmUQflaNxkQo6IOc-kV4T6L44BXrVeqN-dpCPr-KKlLYw650wDQYJKoZIhvcNAQELBQADggIBAJVAa1Bhfa2Eo7TriA_jMA8togoA2SUE7nL6Z99YUQ8LRwKcPkEpSpOsKYWJLaR6gTIoV3EB76hCiBaWN5HV3-CPyTyNsM2JcILsedPGeHMpMuWrbL1Wn9VFkc7B3Y1k3OmcH1480q9RpYIYr-A35zKedgV3AnvmJKAxVhv9GcVx0_CewHMFTryFuFOe78W8nFajutknarupekDXR4tVcmvj_ihJcST0j_Qggeo4_3wKT98CgjmBgjvKCd3Kqg8n9aSDVWyaOZsVOhZj3Fv5rFu895--D4qiPDETozJIyliH-HugoQpqYJaTX10mnmMdCa6aQeW9CEf-5QmbIP0S4uZAf7pKYTNmDQ5z27DVopqaFw00MIVqQkae_zSPX4dsNeeoTTXrwUGqitLaGap5ol81LKD9JdP3nSUYLfq0vLsHNDyNgb306TfbOenRRVsgQS8tJyLcknSKktWD_Qn7E5vjOXprXPrmdp7g5OPvrbz9QkWa1JTRfo2n2AXV02LPFc-UfR9bWCBEIJBxvmbpmqt0MnBTHWnth2b0CU_KJTDCY3kAPLGbOT8A4KiI73pRW-e9SWTaQXskw3Ei_dHRILM_l9OXsqoYHJ4Dd3tbfvmjoNYggSw4j50l3unI9d1qR5xlBFpW5sLr8gKX4bnY4SR2nyNiOQNLyPc0B0nW502aMEUCIQDTGOX-i_QrffJDY8XvKbPwMuBVrOSO-ayvTnWs_WSuDQIgZ7fMAvD_Ezyy5jg6fQeuOkoJi8V2naCtzV-HTly8Nww
|
14
|
+
'{ "registrationData": "BQQtEmhWVgvbh-8GpjsHbj_d5FB9iNoRL8mNEq34-ANufKWUpVdIj6BSB_m3eMoZ3GqnaDy3RA5eWP8mhTkT1Ht3QAk1GsmaPIQgXgvrBkCQoQtMFvmwYPfW5jpRgoMPFxquHS7MTt8lofZkWAK2caHD-YQQdaRBgd22yWIjPuWnHOcwggLiMIHLAgEBMA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNVBAMTEll1YmljbyBVMkYgVGVzdCBDQTAeFw0xNDA1MTUxMjU4NTRaFw0xNDA2MTQxMjU4NTRaMB0xGzAZBgNVBAMTEll1YmljbyBVMkYgVGVzdCBFRTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABNsK2_Uhx1zOY9ym4eglBg2U5idUGU-dJK8mGr6tmUQflaNxkQo6IOc-kV4T6L44BXrVeqN-dpCPr-KKlLYw650wDQYJKoZIhvcNAQELBQADggIBAJVAa1Bhfa2Eo7TriA_jMA8togoA2SUE7nL6Z99YUQ8LRwKcPkEpSpOsKYWJLaR6gTIoV3EB76hCiBaWN5HV3-CPyTyNsM2JcILsedPGeHMpMuWrbL1Wn9VFkc7B3Y1k3OmcH1480q9RpYIYr-A35zKedgV3AnvmJKAxVhv9GcVx0_CewHMFTryFuFOe78W8nFajutknarupekDXR4tVcmvj_ihJcST0j_Qggeo4_3wKT98CgjmBgjvKCd3Kqg8n9aSDVWyaOZsVOhZj3Fv5rFu895--D4qiPDETozJIyliH-HugoQpqYJaTX10mnmMdCa6aQeW9CEf-5QmbIP0S4uZAf7pKYTNmDQ5z27DVopqaFw00MIVqQkae_zSPX4dsNeeoTTXrwUGqitLaGap5ol81LKD9JdP3nSUYLfq0vLsHNDyNgb306TfbOenRRVsgQS8tJyLcknSKktWD_Qn7E5vjOXprXPrmdp7g5OPvrbz9QkWa1JTRfo2n2AXV02LPFc-UfR9bWCBEIJBxvmbpmqt0MnBTHWnth2b0CU_KJTDCY3kAPLGbOT8A4KiI73pRW-e9SWTaQXskw3Ei_dHRILM_l9OXsqoYHJ4Dd3tbfvmjoNYggSw4j50l3unI9d1qR5xlBFpW5sLr8gKX4bnY4SR2nyNiOQNLyPc0B0nW502aMEUCIQDTGOX-i_QrffJDY8XvKbPwMuBVrOSO-ayvTnWs_WSuDQIgZ7fMAvD_Ezyy5jg6fQeuOkoJi8V2naCtzV-HTly8Nww", "clientData": "eyAiY2hhbGxlbmdlIjogInlLQTB4MDc1dGpKLUdFN2ZLVGZuelRPU2FOVU9XUXhSZDlUV3o1YUZPZzgiLCAib3JpZ2luIjogImh0dHA6XC9cL2RlbW8uZXhhbXBsZS5jb20iLCAidHlwIjogIm5hdmlnYXRvci5pZC5maW5pc2hFbnJvbGxtZW50IiB9" }'
|
15
15
|
end
|
16
16
|
|
17
17
|
let(:registration_data_without_padding) {
|
18
|
-
"{\"registrationData\":\"BQT2UXxw7PXHmN5nCj1M3Lq_sibfqQehZbuUV1Vxr1l0J1Gdcv7FEvnPofmrSN44_pz8-XAj7pOpqB79rOphJPf2QM8nt8Jtyyj9_XmZWZTQMg2UVHvrin_Jc4tMHY9QmyCNDmSU9_Bhb-Ei4u5GPgLrpF1TaEYQCqUHboqDKt4x524wggIbMIIBBaADAgECAgR1o_Z1MAsGCSqGSIb3DQEBCzAuMSwwKgYDVQQDEyNZdWJpY28gVTJGIFJvb3QgQ0EgU2VyaWFsIDQ1NzIwMDYzMTAgFw0xNDA4MDEwMDAwMDBaGA8yMDUwMDkwNDAwMDAwMFowKjEoMCYGA1UEAwwfWXViaWNvIFUyRiBFRSBTZXJpYWwgMTk3MzY3OTczMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABBmjfkNqa2mXzVh2ZxuES5coCvvENxDMDLmfd-0ACG0Fu7wR4ZTjKd9KAuidySpfona5csGmlM0Te_Zu35h_wwujEjAQMA4GCisGAQQBgsQKAQIEADALBgkqhkiG9w0BAQsDggEBAb0tuI0-CzSxBg4cAlyD6UyT4cKyJZGVhWdtPgj_mWepT3Tu9jXtdgA5F3jfZtTc2eGxuS-PPvqRAkZd40AXgM8A0YaXPwlT4s0RUTY9Y8aAQzQZeAHuZk3lKKd_LUCg5077dzdt90lC5eVTEduj6cOnHEqnOr2Cv75FuiQXX7QkGQxtoD-otgvhZ2Fjk29o7Iy9ik7ewHGXOfoVw_ruGWi0YfXBTuqEJ6H666vvMN4BZWHtzhC0k5ceQslB9Xdntky-GQgDqNkkBf32GKwAFT9JJrkO2BfsB-wfBrTiHr0AABYNTNKTceA5dtR3UVpI492VUWQbY3YmWUUfKTI7fM4wRgIhAIfEKaF0w43L3RJHXp8qeRKw8Ek0CVcZ6pvBsH3Wo3F1AiEA5w89AFOBrjoSsnuGdUgB4AGxc5bRnV-p8jGUNoVSUwI\",\"version\":\"U2F_V2\",\"challenge\":\"oqDO4u_tTvhm1LhFDVYhFwywQF0PzFsXPgjD-5lKGDY
|
18
|
+
"{\"registrationData\":\"BQT2UXxw7PXHmN5nCj1M3Lq_sibfqQehZbuUV1Vxr1l0J1Gdcv7FEvnPofmrSN44_pz8-XAj7pOpqB79rOphJPf2QM8nt8Jtyyj9_XmZWZTQMg2UVHvrin_Jc4tMHY9QmyCNDmSU9_Bhb-Ei4u5GPgLrpF1TaEYQCqUHboqDKt4x524wggIbMIIBBaADAgECAgR1o_Z1MAsGCSqGSIb3DQEBCzAuMSwwKgYDVQQDEyNZdWJpY28gVTJGIFJvb3QgQ0EgU2VyaWFsIDQ1NzIwMDYzMTAgFw0xNDA4MDEwMDAwMDBaGA8yMDUwMDkwNDAwMDAwMFowKjEoMCYGA1UEAwwfWXViaWNvIFUyRiBFRSBTZXJpYWwgMTk3MzY3OTczMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABBmjfkNqa2mXzVh2ZxuES5coCvvENxDMDLmfd-0ACG0Fu7wR4ZTjKd9KAuidySpfona5csGmlM0Te_Zu35h_wwujEjAQMA4GCisGAQQBgsQKAQIEADALBgkqhkiG9w0BAQsDggEBAb0tuI0-CzSxBg4cAlyD6UyT4cKyJZGVhWdtPgj_mWepT3Tu9jXtdgA5F3jfZtTc2eGxuS-PPvqRAkZd40AXgM8A0YaXPwlT4s0RUTY9Y8aAQzQZeAHuZk3lKKd_LUCg5077dzdt90lC5eVTEduj6cOnHEqnOr2Cv75FuiQXX7QkGQxtoD-otgvhZ2Fjk29o7Iy9ik7ewHGXOfoVw_ruGWi0YfXBTuqEJ6H666vvMN4BZWHtzhC0k5ceQslB9Xdntky-GQgDqNkkBf32GKwAFT9JJrkO2BfsB-wfBrTiHr0AABYNTNKTceA5dtR3UVpI492VUWQbY3YmWUUfKTI7fM4wRgIhAIfEKaF0w43L3RJHXp8qeRKw8Ek0CVcZ6pvBsH3Wo3F1AiEA5w89AFOBrjoSsnuGdUgB4AGxc5bRnV-p8jGUNoVSUwI\",\"version\":\"U2F_V2\",\"challenge\":\"oqDO4u_tTvhm1LhFDVYhFwywQF0PzFsXPgjD-5lKGDY\",\"appId\":\"http://localhost:3000\",\"clientData\":\"eyJ0eXAiOiJuYXZpZ2F0b3IuaWQuZmluaXNoRW5yb2xsbWVudCIsImNoYWxsZW5nZSI6Im9xRE80dV90VHZobTFMaEZEVlloRnd5d1FGMFB6RnNYUGdqRC01bEtHRFk9Iiwib3JpZ2luIjoiaHR0cDovL2xvY2FsaG9zdDozMDAwIiwiY2lkX3B1YmtleSI6IiJ9\"}"
|
19
19
|
}
|
20
20
|
|
21
21
|
let(:app_id) { 'http://demo.example.com' }
|
data/spec/lib/u2f_spec.rb
CHANGED
@@ -5,19 +5,19 @@ describe U2F do
|
|
5
5
|
let(:u2f) { U2F::U2F.new(app_id) }
|
6
6
|
let(:challenge) { 'fEnc9oV79EaBgK5BoNERU5gPKM2XGYWrz4fUjgc0Q7g' }
|
7
7
|
let(:key_handle) do
|
8
|
-
'CTUayZo8hCBeC-sGQJChC0wW-bBg99bmOlGCgw8XGq4dLsxO3yWh9mRYArZxocP5hBB1pEGB3bbJYiM-5acc5w
|
8
|
+
'CTUayZo8hCBeC-sGQJChC0wW-bBg99bmOlGCgw8XGq4dLsxO3yWh9mRYArZxocP5hBB1pEGB3bbJYiM-5acc5w'
|
9
9
|
end
|
10
10
|
let(:certificate) do
|
11
|
-
"MIIC4jCBywIBATANBgkqhkiG9w0BAQsFADAdMRswGQYDVQQDExJZdWJpY28gVTJGIFRlc3QgQ0EwHhcNMTQwNTE1MTI1ODU0WhcNMTQwNjE0MTI1ODU0WjAdMRswGQYDVQQDExJZdWJpY28gVTJGIFRlc3QgRUUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATbCtv1IcdczmPcpuHoJQYNlOYnVBlPnSSvJhq+rZlEH5WjcZEKOiDnPpFeE+i+OAV61XqjfnaQj6\/iipS2MOudMA0GCSqGSIb3DQEBCwUAA4ICAQCVQGtQYX2thKO064gP4zAPLaIKANklBO5y+mffWFEPC0cCnD5BKUqTrCmFiS2keoEyKFdxAe+oQogWljeR1d\/gj8k8jbDNiXCC7HnTxnhzKTLlq2y9Vp\/VRZHOwd2NZNzpnB9ePNKvUaWCGK\/gN+cynnYFdwJ75iSgMVYb\/RnFcdPwnsBzBU68hbhTnu\/FvJxWo7rZJ2q7qXpA10eLVXJr4\/4oSXEk9I\/0IIHqOP98Ck\/fAoI5gYI7ygndyqoPJ\/Wkg1VsmjmbFToWY9xb+axbvPefvg+KojwxE6MySMpYh\/h7oKEKamCWk19dJp5jHQmumkHlvQhH\/uUJmyD9EuLmQH+6SmEzZg0Oc9uw1aKamhcNNDCFakJGnv80j1+HbDXnqE0168FBqorS2hmqeaJfNSyg\/SXT950lGC36tLy7BzQ8jYG99Ok32znp0UVbIEEvLSci3JJ0ipLVg\/0J+xOb4zl6a1z65nae4OTj7628\/UJFmtSU0X6Np9gF1dNizxXPlH0fW1ggRCCQcb5m6ZqrdDJwUx1p7Ydm9AlPyiUwwmN5ADyxmzk\/AOCoiO96UVvnvUlk2kF7JMNxIv3R0SCzP5fTl7KqGByeA3d7W375o6DWIIEsOI+dJd7pyPXdakecZQRaVubC6\/ICl+G52OEkdp8jYjkDS8j3NAdJ1udNmg
|
11
|
+
"MIIC4jCBywIBATANBgkqhkiG9w0BAQsFADAdMRswGQYDVQQDExJZdWJpY28gVTJGIFRlc3QgQ0EwHhcNMTQwNTE1MTI1ODU0WhcNMTQwNjE0MTI1ODU0WjAdMRswGQYDVQQDExJZdWJpY28gVTJGIFRlc3QgRUUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATbCtv1IcdczmPcpuHoJQYNlOYnVBlPnSSvJhq+rZlEH5WjcZEKOiDnPpFeE+i+OAV61XqjfnaQj6\/iipS2MOudMA0GCSqGSIb3DQEBCwUAA4ICAQCVQGtQYX2thKO064gP4zAPLaIKANklBO5y+mffWFEPC0cCnD5BKUqTrCmFiS2keoEyKFdxAe+oQogWljeR1d\/gj8k8jbDNiXCC7HnTxnhzKTLlq2y9Vp\/VRZHOwd2NZNzpnB9ePNKvUaWCGK\/gN+cynnYFdwJ75iSgMVYb\/RnFcdPwnsBzBU68hbhTnu\/FvJxWo7rZJ2q7qXpA10eLVXJr4\/4oSXEk9I\/0IIHqOP98Ck\/fAoI5gYI7ygndyqoPJ\/Wkg1VsmjmbFToWY9xb+axbvPefvg+KojwxE6MySMpYh\/h7oKEKamCWk19dJp5jHQmumkHlvQhH\/uUJmyD9EuLmQH+6SmEzZg0Oc9uw1aKamhcNNDCFakJGnv80j1+HbDXnqE0168FBqorS2hmqeaJfNSyg\/SXT950lGC36tLy7BzQ8jYG99Ok32znp0UVbIEEvLSci3JJ0ipLVg\/0J+xOb4zl6a1z65nae4OTj7628\/UJFmtSU0X6Np9gF1dNizxXPlH0fW1ggRCCQcb5m6ZqrdDJwUx1p7Ydm9AlPyiUwwmN5ADyxmzk\/AOCoiO96UVvnvUlk2kF7JMNxIv3R0SCzP5fTl7KqGByeA3d7W375o6DWIIEsOI+dJd7pyPXdakecZQRaVubC6\/ICl+G52OEkdp8jYjkDS8j3NAdJ1udNmg"
|
12
12
|
end
|
13
13
|
let(:registration_data_json) do
|
14
14
|
'{ "registrationData": "BQQtEmhWVgvbh-8GpjsHbj_d5FB9iNoRL8mNEq34-ANufKWUpVdIj6BSB_m3eMoZ3GqnaDy3RA5eWP8mhTkT1Ht3QAk1GsmaPIQgXgvrBkCQoQtMFvmwYPfW5jpRgoMPFxquHS7MTt8lofZkWAK2caHD-YQQdaRBgd22yWIjPuWnHOcwggLiMIHLAgEBMA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNVBAMTEll1YmljbyBVMkYgVGVzdCBDQTAeFw0xNDA1MTUxMjU4NTRaFw0xNDA2MTQxMjU4NTRaMB0xGzAZBgNVBAMTEll1YmljbyBVMkYgVGVzdCBFRTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABNsK2_Uhx1zOY9ym4eglBg2U5idUGU-dJK8mGr6tmUQflaNxkQo6IOc-kV4T6L44BXrVeqN-dpCPr-KKlLYw650wDQYJKoZIhvcNAQELBQADggIBAJVAa1Bhfa2Eo7TriA_jMA8togoA2SUE7nL6Z99YUQ8LRwKcPkEpSpOsKYWJLaR6gTIoV3EB76hCiBaWN5HV3-CPyTyNsM2JcILsedPGeHMpMuWrbL1Wn9VFkc7B3Y1k3OmcH1480q9RpYIYr-A35zKedgV3AnvmJKAxVhv9GcVx0_CewHMFTryFuFOe78W8nFajutknarupekDXR4tVcmvj_ihJcST0j_Qggeo4_3wKT98CgjmBgjvKCd3Kqg8n9aSDVWyaOZsVOhZj3Fv5rFu895--D4qiPDETozJIyliH-HugoQpqYJaTX10mnmMdCa6aQeW9CEf-5QmbIP0S4uZAf7pKYTNmDQ5z27DVopqaFw00MIVqQkae_zSPX4dsNeeoTTXrwUGqitLaGap5ol81LKD9JdP3nSUYLfq0vLsHNDyNgb306TfbOenRRVsgQS8tJyLcknSKktWD_Qn7E5vjOXprXPrmdp7g5OPvrbz9QkWa1JTRfo2n2AXV02LPFc-UfR9bWCBEIJBxvmbpmqt0MnBTHWnth2b0CU_KJTDCY3kAPLGbOT8A4KiI73pRW-e9SWTaQXskw3Ei_dHRILM_l9OXsqoYHJ4Dd3tbfvmjoNYggSw4j50l3unI9d1qR5xlBFpW5sLr8gKX4bnY4SR2nyNiOQNLyPc0B0nW502aMEUCIQDTGOX-i_QrffJDY8XvKbPwMuBVrOSO-ayvTnWs_WSuDQIgZ7fMAvD_Ezyy5jg6fQeuOkoJi8V2naCtzV-HTly8Nww=", "clientData": "eyAiY2hhbGxlbmdlIjogInlLQTB4MDc1dGpKLUdFN2ZLVGZuelRPU2FOVU9XUXhSZDlUV3o1YUZPZzgiLCAib3JpZ2luIjogImh0dHA6XC9cL2RlbW8uZXhhbXBsZS5jb20iLCAidHlwIjogIm5hdmlnYXRvci5pZC5maW5pc2hFbnJvbGxtZW50IiB9" }'
|
15
15
|
end
|
16
16
|
let(:public_key) do
|
17
|
-
|
17
|
+
U2F.urlsafe_decode64("BC0SaFZWC9uH7wamOwduP93kUH2I2hEvyY0Srfj4A258pZSlV0iPoFIH+bd4yhncaqdoPLdEDl5Y\/yaFORPUe3c")
|
18
18
|
end
|
19
19
|
let(:json_response) do
|
20
|
-
'{ "signatureData": "AQAAAAQwRQIhAI6FSrMD3KUUtkpiP0jpIEakql-HNhwWFngyw553pS1CAiAKLjACPOhxzZXuZsVO8im-HStEcYGC50PKhsGp_SUAng
|
20
|
+
'{ "signatureData": "AQAAAAQwRQIhAI6FSrMD3KUUtkpiP0jpIEakql-HNhwWFngyw553pS1CAiAKLjACPOhxzZXuZsVO8im-HStEcYGC50PKhsGp_SUAng", "clientData": "eyAiY2hhbGxlbmdlIjogImZFbmM5b1Y3OUVhQmdLNUJvTkVSVTVnUEtNMlhHWVdyejRmVWpnYzBRN2ciLCAib3JpZ2luIjogImh0dHA6XC9cL2RlbW8uZXhhbXBsZS5jb20iLCAidHlwIjogIm5hdmlnYXRvci5pZC5nZXRBc3NlcnRpb24iIH0=", "keyHandle": "CTUayZo8hCBeC-sGQJChC0wW-bBg99bmOlGCgw8XGq4dLsxO3yWh9mRYArZxocP5hBB1pEGB3bbJYiM-5acc5w" }'
|
21
21
|
end
|
22
22
|
let(:registration) do
|
23
23
|
U2F::Registration.new(key_handle, public_key, certificate)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: u2f
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Johan Brissmyr
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-11-
|
12
|
+
date: 2014-11-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|