class U2F::RegisterResponse

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

Constants

KEY_HANDLE_LENGTH_LENGTH
KEY_HANDLE_LENGTH_OFFSET
KEY_HANDLE_OFFSET
PUBLIC_KEY_LENGTH
PUBLIC_KEY_OFFSET

Attributes

client_data[RW]
client_data_json[RW]
registration_data_raw[RW]

Public Class Methods

load_from_json(json) click to toggle source
# 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

Public Instance Methods

certificate() click to toggle source

The attestation certificate in Base64 encoded X.509 DER format

# File lib/u2f/register_response.rb, line 35
def certificate
  Base64.strict_encode64(parsed_certificate.to_der)
end
certificate_length() click to toggle source

Length of the attestation certificate

# File lib/u2f/register_response.rb, line 47
def certificate_length
  parsed_certificate.to_der.bytesize
end
key_handle() click to toggle source

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

# File lib/u2f/register_response.rb, line 53
def key_handle
  ::U2F.urlsafe_encode64(key_handle_raw)
end
key_handle_length() click to toggle source

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

# 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_raw() click to toggle source
# File lib/u2f/register_response.rb, line 57
def key_handle_raw
  registration_data_raw.byteslice(KEY_HANDLE_OFFSET, key_handle_length)
end
parsed_certificate() click to toggle source

The parsed attestation certificate

# File lib/u2f/register_response.rb, line 41
def parsed_certificate
  OpenSSL::X509::Certificate.new(certificate_bytes)
end
public_key() click to toggle source

Returns the public key, extracted from the registration data

# File lib/u2f/register_response.rb, line 69
def public_key
  # Base64 encode without linefeeds
  Base64.strict_encode64(public_key_raw)
end
public_key_raw() click to toggle source
# File lib/u2f/register_response.rb, line 74
def public_key_raw
  registration_data_raw.byteslice(PUBLIC_KEY_OFFSET, PUBLIC_KEY_LENGTH)
end
signature() click to toggle source

Returns the signature, extracted from the registration data

# 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) click to toggle source

Verifies the registration data against the app id

# 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",
    ::U2F::DIGEST.digest(app_id),
    ::U2F::DIGEST.digest(client_data_json),
    key_handle_raw,
    public_key_raw
  ].join

  begin
    parsed_certificate.public_key.verify(::U2F::DIGEST.new, signature, data)
  rescue OpenSSL::PKey::PKeyError
    false
  end
end

Private Instance Methods

certificate_bytes() click to toggle source
# File lib/u2f/register_response.rb, line 107
def certificate_bytes
  base_offset = KEY_HANDLE_OFFSET + key_handle_length
  registration_data_raw.byteslice(base_offset..-1)
end