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