Class: U2F::RegisterResponse

Inherits:
Object
  • Object
show all
Defined in:
lib/u2f/register_response.rb

Overview

Representation of a U2F registration response. See chapter 4.3: fidoalliance.org/specs/fido-u2f-raw-message-formats-v1.0-rd-20141008.pdf

Constant Summary collapse

PUBLIC_KEY_OFFSET =
1
PUBLIC_KEY_LENGTH =
65
KEY_HANDLE_LENGTH_LENGTH =
1
KEY_HANDLE_LENGTH_OFFSET =
PUBLIC_KEY_OFFSET + PUBLIC_KEY_LENGTH
KEY_HANDLE_OFFSET =
KEY_HANDLE_LENGTH_OFFSET + KEY_HANDLE_LENGTH_LENGTH

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#client_dataObject

Returns the value of attribute client_data.



7
8
9
# File 'lib/u2f/register_response.rb', line 7

def client_data
  @client_data
end

#client_data_jsonObject

Returns the value of attribute client_data_json.



7
8
9
# File 'lib/u2f/register_response.rb', line 7

def client_data_json
  @client_data_json
end

#registration_data_rawObject

Returns the value of attribute registration_data_raw.



7
8
9
# File 'lib/u2f/register_response.rb', line 7

def registration_data_raw
  @registration_data_raw
end

Class Method Details

.load_from_json(json) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/u2f/register_response.rb', line 15

def self.load_from_json(json)
  # TODO: validate
  data = JSON.parse(json)

  if data['errorCode'] && data['errorCode'] > 0
    fail RegistrationError, :code => data['errorCode']
  end

  instance = new
  instance.client_data_json =
    ::U2F.urlsafe_decode64(data['clientData'])
  instance.client_data =
    ClientData.load_from_json(instance.client_data_json)
  instance.registration_data_raw =
    ::U2F.urlsafe_decode64(data['registrationData'])
  instance
end

Instance Method Details

#certificateObject

The attestation certificate in Base64 encoded X.509 DER format



35
36
37
# File 'lib/u2f/register_response.rb', line 35

def certificate
  Base64.strict_encode64(parsed_certificate.to_der)
end

#certificate_lengthObject

Length of the attestation certificate



47
48
49
# File 'lib/u2f/register_response.rb', line 47

def certificate_length
  parsed_certificate.to_der.bytesize
end

#key_handleObject

Returns the key handle from registration data, URL safe base64 encoded



53
54
55
# File 'lib/u2f/register_response.rb', line 53

def key_handle
  ::U2F.urlsafe_encode64(key_handle_raw)
end

#key_handle_lengthObject

Returns the length of the key handle, extracted from the registration data



63
64
65
# File 'lib/u2f/register_response.rb', line 63

def key_handle_length
  registration_data_raw.byteslice(KEY_HANDLE_LENGTH_OFFSET).unpack('C').first
end

#key_handle_rawObject



57
58
59
# File 'lib/u2f/register_response.rb', line 57

def key_handle_raw
  registration_data_raw.byteslice(KEY_HANDLE_OFFSET, key_handle_length)
end

#parsed_certificateObject

The parsed attestation certificate



41
42
43
# File 'lib/u2f/register_response.rb', line 41

def parsed_certificate
  OpenSSL::X509::Certificate.new(certificate_bytes)
end

#public_keyObject

Returns the public key, extracted from the registration data



69
70
71
72
# File 'lib/u2f/register_response.rb', line 69

def public_key
  # Base64 encode without linefeeds
  Base64.strict_encode64(public_key_raw)
end

#public_key_rawObject



74
75
76
# File 'lib/u2f/register_response.rb', line 74

def public_key_raw
  registration_data_raw.byteslice(PUBLIC_KEY_OFFSET, PUBLIC_KEY_LENGTH)
end

#signatureObject

Returns the signature, extracted from the registration data



80
81
82
83
# File 'lib/u2f/register_response.rb', line 80

def signature
  registration_data_raw.byteslice(
    (KEY_HANDLE_OFFSET + key_handle_length + certificate_length)..-1)
end

#verify(app_id) ⇒ Object

Verifies the registration data against the app id



87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/u2f/register_response.rb', line 87

def verify(app_id)
  # Chapter 4.3 in
  # http://fidoalliance.org/specs/fido-u2f-raw-message-formats-v1.0-rd-20141008.pdf
  data = [
    "\x00",
    Digest::SHA256.digest(app_id),
    Digest::SHA256.digest(client_data_json),
    key_handle_raw,
    public_key_raw
  ].join

  parsed_certificate.public_key.verify(OpenSSL::Digest::SHA256.new, signature, data)
end