webauthn 0.0.0 → 0.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6e28ff07e2d21ef95903ef75e6f90afbf15001c045491eb7919c9a76219d75c1
4
- data.tar.gz: 2f5412e554ee3580e6183b423982aabc2afb70ff55f6bb2ef1f614662ff1a610
3
+ metadata.gz: 171f428eb4d325429c9a5e94fb5c217b4449fd1cd0d337a1e826f8c63754405b
4
+ data.tar.gz: 0fa1366a9247171005f68fed977ad7bab8d4dbb89485a21be3a4017aa22d034f
5
5
  SHA512:
6
- metadata.gz: 55e257566ed6b03d5eaee26a7042f0e8aef7c6a3031b359c8a0f2e28faae7d5cba02c941d696f11e2ca4ffdf8a11a3cc27dadd02142e58d1aedb520171436c92
7
- data.tar.gz: 74ac5d43265be731182304f227cf4ef34642eddc5de54849f270f114279ced4ffe32c18e02e12b9c639edf50fb64548d6fc406408170d37c5f4994ddd3d6d2e4
6
+ metadata.gz: dd05fe7063e2532255cc2f8e79c5faa72a4e625f35d3e56d2a21320c0d3ce16bd21483578af8ce22d65951cee8de19c765b8245132a407d95c5b82809444f649
7
+ data.tar.gz: ed40d6cc3da9d6c331b95180cabefd781df08f3bba653501d6a7248cc567a82615a4fa94429e46b68e09764458af9b108a4d8bd201c721154efbaef09e89d1b0
data/.gitignore CHANGED
@@ -11,3 +11,4 @@
11
11
  .rspec_status
12
12
 
13
13
  /Gemfile.lock
14
+ /.byebug_history
@@ -0,0 +1,24 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.5
3
+ DisabledByDefault: true
4
+
5
+ Bundler:
6
+ Enabled: true
7
+
8
+ Gemspec:
9
+ Enabled: true
10
+
11
+ Layout:
12
+ Enabled: true
13
+
14
+ Performance:
15
+ Enabled: true
16
+
17
+ Security:
18
+ Enabled: true
19
+
20
+ Style/FrozenStringLiteralComment:
21
+ Enabled: true
22
+
23
+ Style/RedundantFreeze:
24
+ Enabled: true
@@ -0,0 +1,13 @@
1
+ # Changelog
2
+
3
+ ## [Unreleased]
4
+
5
+ ## [v0.1.0] - 2018-05-25
6
+
7
+ ### Added
8
+
9
+ - `WebAuthn.credential_creation_options` to initiate registration
10
+ - `WebAuthn::AuthenticatorAttestationResponse.valid?` can be used to validate fido-u2f attestations returned by the browser
11
+
12
+ [Unreleased]: https://github.com/cedarcode/webauthn-ruby/compare/v0.1.0...HEAD/
13
+ [v0.1.0]: https://github.com/cedarcode/webauthn-ruby/compare/v0.0.0...v0.1.0/
data/Gemfile CHANGED
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "https://rubygems.org"
2
4
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
6
 
5
7
  # Specify your gem's dependencies in webauthn.gemspec
6
8
  gemspec
data/README.md CHANGED
@@ -1,8 +1,31 @@
1
- # Webauthn
1
+ # WebAuthn
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/webauthn`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ Easily implement WebAuthn in your ruby web server
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ [![Gem](https://img.shields.io/gem/v/webauthn.svg?style=flat-square)](https://rubygems.org/gems/webauthn)
6
+ [![Travis](https://img.shields.io/travis/cedarcode/webauthn-ruby.svg?style=flat-square)](https://travis-ci.org/cedarcode/webauthn-ruby)
7
+
8
+ ## WARNING: This gem is in the early development phase. Use on production at your own risk.
9
+
10
+ ## What is WebAuthn?
11
+
12
+ - [WebAuthn article with Google IO 2018 talk](https://developers.google.com/web/updates/2018/05/webauthn)
13
+ - [Web Authentication API draft article by Mozilla](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API)
14
+ - [W3C Draft Recommendation](https://w3c.github.io/webauthn/)
15
+
16
+ ## Prerequisites
17
+
18
+ ### User Agent compatibility
19
+
20
+ So far, the only browser that have web authentication support are:
21
+ - Mozilla Firefox Quantum 60+ (Enabled by default).
22
+ - Google Chrome 65+ (Disabled by default, go to chrome://flags to enable Web Authentication API feature). Note: it is enabled by default in 67+ as stated [here](https://www.chromestatus.com/feature/5669923372138496).
23
+
24
+ ### Authenticator devices
25
+
26
+ These [USB keys from Yubico](https://www.yubico.com/product/security-key-by-yubico/) were used as authenticator devices during the development of this gem.
27
+ Firefox states ([Firefox 60 release notes](https://www.mozilla.org/en-US/firefox/60.0/releasenotes/)) they only support USB FIDO2 or FIDO U2F enabled devices in their current implementation (version 60).
28
+ It's up to the gem's user to verify user agent compatibility if any other devise wants to be used as the authenticator component.
6
29
 
7
30
  ## Installation
8
31
 
@@ -22,17 +45,65 @@ Or install it yourself as:
22
45
 
23
46
  ## Usage
24
47
 
25
- TODO: Write usage instructions here
48
+ ### Registration
49
+
50
+ #### Initiation phase
51
+
52
+ ```ruby
53
+ credential_creation_options = WebAuthn.credential_creation_options
54
+
55
+ # Store the newly generated challenge somewhere so you can have it
56
+ # for the validation phase.
57
+ #
58
+ # You can read it from the resulting options:
59
+ credential_creation_options[:challenge]
60
+
61
+ # Send `credential_creation_options` to the browser, so that they can be used
62
+ # to call `navigator.credentials.create({ "publicKey": credentialCreationOptions })`
63
+ ```
64
+
65
+ #### Validation phase
66
+
67
+ ```ruby
68
+ attestation_object = "..." # As came from the browser
69
+ client_data_json = "..." # As came from the browser
70
+
71
+ attestation_response = WebAuthn::AuthenticatorAttestationResponse.new(
72
+ attestation_object: attestation_object,
73
+ client_data_json: client_data_json
74
+ )
75
+
76
+ # This value needs to match `window.location.origin` evaluated by
77
+ # the User Agent as part of the validation phase.
78
+ original_origin = "https://www.example.com"
79
+
80
+ if attestation_response.valid?(original_challenge, original_origin)
81
+ # Register the new user along with it's new `credential_id` for future authentications
82
+ # Access the new user credential by invoking `attestation_response.credential_id`
83
+ else
84
+ # Handle error
85
+ end
86
+ ```
87
+
88
+ ### Authentication
89
+
90
+ #### Initiation phase
91
+
92
+ *Currently under development*
93
+
94
+ #### Validation phase
95
+
96
+ *Currently under development*
26
97
 
27
98
  ## Development
28
99
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
100
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake` to run the tests and code-style checks. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
101
 
31
102
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
103
 
33
104
  ## Contributing
34
105
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/webauthn.
106
+ Bug reports and pull requests are welcome on GitHub at https://github.com/cedarcode/webauthn-ruby.
36
107
 
37
108
  ## License
38
109
 
data/Rakefile CHANGED
@@ -1,6 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/gem_tasks"
2
4
  require "rspec/core/rake_task"
5
+ require "rubocop/rake_task"
3
6
 
4
7
  RSpec::Core::RakeTask.new(:spec)
8
+ RuboCop::RakeTask.new
5
9
 
6
- task :default => :spec
10
+ task :default => [:rubocop, :spec]
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require "bundler/setup"
4
5
  require "webauthn"
@@ -1,5 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "webauthn/authenticator_attestation_response"
1
4
  require "webauthn/version"
2
5
 
3
- module Webauthn
4
- # Your code goes here...
6
+ require "securerandom"
7
+ require "base64"
8
+ require "json"
9
+
10
+ module WebAuthn
11
+ ES256_ALGORITHM = { type: "public-key", alg: -7 }.freeze
12
+ RP_NAME = "web-server"
13
+ USER_ID = "1"
14
+ USER_NAME = "web-user"
15
+ CREATE_TYPE = "webauthn.create"
16
+
17
+ def self.credential_creation_options
18
+ {
19
+ challenge: Base64.urlsafe_encode64(SecureRandom.random_bytes(16)),
20
+ pubKeyCredParams: [ES256_ALGORITHM],
21
+ rp: { name: RP_NAME },
22
+ user: { name: USER_NAME, displayName: USER_NAME, id: Base64.urlsafe_encode64(USER_ID) }
23
+ }
24
+ end
5
25
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WebAuthn
4
+ module AttestationStatement
5
+ ATTESTATION_FORMAT_NONE = "none"
6
+ ATTESTATION_FORMAT_FIDO_U2F = "fido-u2f"
7
+
8
+ def self.from(format, statement)
9
+ case format
10
+ when ATTESTATION_FORMAT_NONE
11
+ require "webauthn/attestation_statement/none"
12
+ WebAuthn::AttestationStatement::None.new(statement)
13
+ when ATTESTATION_FORMAT_FIDO_U2F
14
+ require "webauthn/attestation_statement/fido_u2f"
15
+ WebAuthn::AttestationStatement::FidoU2f.new(statement)
16
+ else
17
+ raise "Unsupported attestation format '#{attestation_format}'"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WebAuthn
4
+ module AttestationStatement
5
+ class Base
6
+ def initialize(statement)
7
+ @statement = statement
8
+ end
9
+
10
+ def valid?(*args)
11
+ raise NotImpelementedError
12
+ end
13
+
14
+ private
15
+
16
+ attr_reader :statement
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openssl"
4
+ require "webauthn/attestation_statement/base"
5
+
6
+ module WebAuthn
7
+ module AttestationStatement
8
+ class FidoU2f < Base
9
+ VALID_ATTESTATION_CERTIFICATE_COUNT = 1
10
+
11
+ def valid?(authenticator_data, client_data_hash)
12
+ valid_format? &&
13
+ valid_certificate_public_key? &&
14
+ valid_signature?(authenticator_data, client_data_hash)
15
+ end
16
+
17
+ private
18
+
19
+ def signature
20
+ statement["sig"]
21
+ end
22
+
23
+ def valid_format?
24
+ !!(raw_attestation_certificates && signature) &&
25
+ raw_attestation_certificates.length == VALID_ATTESTATION_CERTIFICATE_COUNT
26
+ end
27
+
28
+ def valid_certificate_public_key?
29
+ certificate_public_key.is_a?(OpenSSL::PKey::EC) && certificate_public_key.check_key
30
+ end
31
+
32
+ def certificate_public_key
33
+ attestation_certificate.public_key
34
+ end
35
+
36
+ def attestation_certificate
37
+ @attestation_certificate ||= OpenSSL::X509::Certificate.new(raw_attestation_certificates[0])
38
+ end
39
+
40
+ def raw_attestation_certificates
41
+ statement["x5c"]
42
+ end
43
+
44
+ def valid_signature?(authenticator_data, client_data_hash)
45
+ certificate_public_key.verify(
46
+ "SHA256",
47
+ signature,
48
+ verification_data(authenticator_data, client_data_hash)
49
+ )
50
+ end
51
+
52
+ def verification_data(authenticator_data, client_data_hash)
53
+ "\x00" +
54
+ authenticator_data.rp_id_hash +
55
+ client_data_hash +
56
+ authenticator_data.credential_id +
57
+ authenticator_data.credential_public_key
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "webauthn/attestation_statement/base"
4
+
5
+ module WebAuthn
6
+ module AttestationStatement
7
+ class None < Base
8
+ def valid?(*args)
9
+ true
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cbor"
4
+ require "uri"
5
+ require "openssl"
6
+
7
+ require "webauthn/authenticator_data"
8
+ require "webauthn/attestation_statement"
9
+ require "webauthn/client_data"
10
+
11
+ module WebAuthn
12
+ class AuthenticatorAttestationResponse
13
+ def initialize(attestation_object:, client_data_json:)
14
+ @attestation_object = attestation_object
15
+ @client_data_json = client_data_json
16
+ end
17
+
18
+ def valid?(original_challenge, original_origin)
19
+ valid_type? &&
20
+ valid_challenge?(original_challenge) &&
21
+ valid_origin?(original_origin) &&
22
+ valid_rp_id?(original_origin) &&
23
+ authenticator_data.valid? &&
24
+ user_present? &&
25
+ attestation_statement.valid?(authenticator_data, client_data.hash)
26
+ end
27
+
28
+ def credential_id
29
+ authenticator_data.credential_id
30
+ end
31
+
32
+ private
33
+
34
+ attr_reader :attestation_object, :client_data_json
35
+
36
+ def valid_type?
37
+ client_data.type == CREATE_TYPE
38
+ end
39
+
40
+ def valid_challenge?(original_challenge)
41
+ Base64.urlsafe_decode64(client_data.challenge) == Base64.urlsafe_decode64(original_challenge)
42
+ end
43
+
44
+ def valid_origin?(original_origin)
45
+ client_data.origin == original_origin
46
+ end
47
+
48
+ def attestation_statement
49
+ @attestation_statement ||=
50
+ WebAuthn::AttestationStatement.from(attestation["fmt"], attestation["attStmt"])
51
+ end
52
+
53
+ def valid_rp_id?(original_origin)
54
+ domain = URI.parse(original_origin).host
55
+
56
+ OpenSSL::Digest::SHA256.digest(domain) == authenticator_data.rp_id_hash
57
+ end
58
+
59
+ def user_present?
60
+ authenticator_data.user_present?
61
+ end
62
+
63
+ def client_data
64
+ @client_data ||= WebAuthn::ClientData.new(client_data_json)
65
+ end
66
+
67
+ def authenticator_data
68
+ @authenticator_data ||= WebAuthn::AuthenticatorData.new(attestation["authData"])
69
+ end
70
+
71
+ def attestation_format
72
+ attestation["fmt"]
73
+ end
74
+
75
+ def attestation
76
+ @attestation ||= CBOR.decode(Base64.urlsafe_decode64(attestation_object))
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "webauthn/authenticator_data/attested_credential_data"
4
+
5
+ module WebAuthn
6
+ class AuthenticatorData
7
+ RP_ID_HASH_POSITION = 0
8
+
9
+ RP_ID_HASH_LENGTH = 32
10
+ FLAGS_LENGTH = 1
11
+ SIGN_COUNT_LENGTH = 4
12
+
13
+ USER_PRESENT_FLAG_POSITION = 0
14
+ ATTESTED_CREDENTIAL_DATA_INCLUDED_FLAG_POSITION = 6
15
+
16
+ def initialize(data)
17
+ @data = data
18
+ end
19
+
20
+ def valid?
21
+ if attested_credential_data_included?
22
+ data.length > base_length && attested_credential_data.valid?
23
+ else
24
+ data.length == base_length
25
+ end
26
+ end
27
+
28
+ def user_present?
29
+ flags[USER_PRESENT_FLAG_POSITION] == "1"
30
+ end
31
+
32
+ def rp_id_hash
33
+ @rp_id_hash ||=
34
+ if valid?
35
+ data_at(RP_ID_HASH_POSITION, RP_ID_HASH_LENGTH)
36
+ end
37
+ end
38
+
39
+ def credential_id
40
+ @credential_id ||= attested_credential_data.id
41
+ end
42
+
43
+ def credential_public_key
44
+ @credential_public_key ||= attested_credential_data.public_key
45
+ end
46
+
47
+ private
48
+
49
+ attr_reader :data
50
+
51
+ def attested_credential_data
52
+ @attested_credential_data ||=
53
+ AttestedCredentialData.new(data_at(attested_credential_data_position))
54
+ end
55
+
56
+ def attested_credential_data_position
57
+ base_length
58
+ end
59
+
60
+ def base_length
61
+ RP_ID_HASH_LENGTH + FLAGS_LENGTH + SIGN_COUNT_LENGTH
62
+ end
63
+
64
+ def flags
65
+ @flags ||= data_at(flags_position, FLAGS_LENGTH).unpack("b*").first
66
+ end
67
+
68
+ def flags_position
69
+ RP_ID_HASH_LENGTH
70
+ end
71
+
72
+ def attested_credential_data_included?
73
+ flags[ATTESTED_CREDENTIAL_DATA_INCLUDED_FLAG_POSITION] == "1"
74
+ end
75
+
76
+ def data_at(position, length = nil)
77
+ length ||= data.size - position
78
+
79
+ data[position..(position + length - 1)]
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "webauthn/authenticator_data/attested_credential_data/public_key_u2f"
4
+
5
+ module WebAuthn
6
+ class AuthenticatorData
7
+ class AttestedCredentialData
8
+ AAGUID_LENGTH = 16
9
+ ID_LENGTH_LENGTH = 2
10
+
11
+ UINT16_BIG_ENDIAN_FORMAT = "n*"
12
+
13
+ def initialize(data)
14
+ @data = data
15
+ end
16
+
17
+ def valid?
18
+ data.length >= AAGUID_LENGTH + ID_LENGTH_LENGTH && public_key.valid?
19
+ end
20
+
21
+ def id
22
+ if valid?
23
+ data_at(id_position, id_length)
24
+ end
25
+ end
26
+
27
+ def public_key
28
+ @public_key ||= PublicKeyU2f.new(data_at(public_key_position, public_key_length))
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :data
34
+
35
+ def id_position
36
+ id_length_position + ID_LENGTH_LENGTH
37
+ end
38
+
39
+ def id_length
40
+ @id_length ||=
41
+ data_at(id_length_position, ID_LENGTH_LENGTH)
42
+ .unpack(UINT16_BIG_ENDIAN_FORMAT)
43
+ .first
44
+ end
45
+
46
+ def id_length_position
47
+ AAGUID_LENGTH
48
+ end
49
+
50
+ def public_key_position
51
+ id_position + id_length
52
+ end
53
+
54
+ def public_key_length
55
+ data.size - (AAGUID_LENGTH + ID_LENGTH_LENGTH + id_length)
56
+ end
57
+
58
+ def data_at(position, length = nil)
59
+ length ||= data.size - position
60
+
61
+ data[position..(position + length - 1)]
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WebAuthn
4
+ class AuthenticatorData
5
+ class AttestedCredentialData
6
+ class PublicKeyU2f
7
+ COORDINATE_LENGTH = 32
8
+ X_COORDINATE_KEY = -2
9
+ Y_COORDINATE_KEY = -3
10
+
11
+ def initialize(data)
12
+ @data = data
13
+ end
14
+
15
+ def valid?
16
+ data.size >= COORDINATE_LENGTH * 2 &&
17
+ x_coordinate.length == COORDINATE_LENGTH &&
18
+ y_coordinate.length == COORDINATE_LENGTH
19
+ end
20
+
21
+ def to_str
22
+ "\x04" + x_coordinate + y_coordinate
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :data
28
+
29
+ def x_coordinate
30
+ decoded_data[X_COORDINATE_KEY]
31
+ end
32
+
33
+ def y_coordinate
34
+ decoded_data[Y_COORDINATE_KEY]
35
+ end
36
+
37
+ def decoded_data
38
+ @decoded_data ||= CBOR.decode(data)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openssl"
4
+
5
+ module WebAuthn
6
+ class ClientData
7
+ def initialize(client_data_json)
8
+ @client_data_json = client_data_json
9
+ end
10
+
11
+ def type
12
+ data["type"]
13
+ end
14
+
15
+ def challenge
16
+ data["challenge"]
17
+ end
18
+
19
+ def origin
20
+ data["origin"]
21
+ end
22
+
23
+ def hash
24
+ OpenSSL::Digest::SHA256.digest(decoded_client_data_json)
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :client_data_json
30
+
31
+ def decoded_client_data_json
32
+ @decoded_client_data_json ||= Base64.urlsafe_decode64(client_data_json)
33
+ end
34
+
35
+ def data
36
+ @data ||=
37
+ begin
38
+ if client_data_json
39
+ JSON.parse(decoded_client_data_json)
40
+ else
41
+ raise "Missing client_data_json"
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,3 +1,5 @@
1
- module Webauthn
2
- VERSION = "0.0.0"
1
+ # frozen_string_literal: true
2
+
3
+ module WebAuthn
4
+ VERSION = "0.1.0"
3
5
  end
@@ -1,25 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  lib = File.expand_path("../lib", __FILE__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
5
  require "webauthn/version"
4
6
 
5
7
  Gem::Specification.new do |spec|
6
8
  spec.name = "webauthn"
7
- spec.version = Webauthn::VERSION
8
- spec.authors = ["Gonzalo Rodriguez"]
9
- spec.email = ["gonzalo0@cedarcode.com"]
9
+ spec.version = WebAuthn::VERSION
10
+ spec.authors = ["Gonzalo Rodriguez", "Braulio Martinez"]
11
+ spec.email = ["gonzalo@cedarcode.com", "braulio@cedarcode.com"]
10
12
 
11
13
  spec.summary = %q{Web Authentication API Relying Party in ruby}
12
- spec.homepage = "https://github.com/cedarcode/webauthn"
14
+ spec.homepage = "https://github.com/cedarcode/webauthn-ruby"
13
15
  spec.license = "MIT"
14
16
 
15
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ spec.metadata = {
18
+ "bug_tracker_uri" => "https://github.com/cedarcode/webauthn-ruby/issues",
19
+ "changelog_uri" => "https://github.com/cedarcode/webauthn-ruby/blob/master/CHANGELOG.md",
20
+ "source_code_uri" => "https://github.com/cedarcode/webauthn-ruby"
21
+ }
22
+
23
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
16
24
  f.match(%r{^(test|spec|features)/})
17
25
  end
18
26
  spec.bindir = "exe"
19
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
28
  spec.require_paths = ["lib"]
21
29
 
30
+ spec.add_dependency "cbor", "~> 0.5.9.2"
31
+
22
32
  spec.add_development_dependency "bundler", "~> 1.16"
33
+ spec.add_development_dependency "byebug", "~> 10.0"
23
34
  spec.add_development_dependency "rake", "~> 10.0"
24
35
  spec.add_development_dependency "rspec", "~> 3.0"
36
+ spec.add_development_dependency "rubocop", "0.56.0"
25
37
  end
metadata CHANGED
@@ -1,15 +1,30 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webauthn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gonzalo Rodriguez
8
+ - Braulio Martinez
8
9
  autorequire:
9
10
  bindir: exe
10
11
  cert_chain: []
11
- date: 2018-05-09 00:00:00.000000000 Z
12
+ date: 2018-05-25 00:00:00.000000000 Z
12
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: cbor
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: 0.5.9.2
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: 0.5.9.2
13
28
  - !ruby/object:Gem::Dependency
14
29
  name: bundler
15
30
  requirement: !ruby/object:Gem::Requirement
@@ -24,6 +39,20 @@ dependencies:
24
39
  - - "~>"
25
40
  - !ruby/object:Gem::Version
26
41
  version: '1.16'
42
+ - !ruby/object:Gem::Dependency
43
+ name: byebug
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '10.0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '10.0'
27
56
  - !ruby/object:Gem::Dependency
28
57
  name: rake
29
58
  requirement: !ruby/object:Gem::Requirement
@@ -52,16 +81,33 @@ dependencies:
52
81
  - - "~>"
53
82
  - !ruby/object:Gem::Version
54
83
  version: '3.0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rubocop
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '='
89
+ - !ruby/object:Gem::Version
90
+ version: 0.56.0
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '='
96
+ - !ruby/object:Gem::Version
97
+ version: 0.56.0
55
98
  description:
56
99
  email:
57
- - gonzalo0@cedarcode.com
100
+ - gonzalo@cedarcode.com
101
+ - braulio@cedarcode.com
58
102
  executables: []
59
103
  extensions: []
60
104
  extra_rdoc_files: []
61
105
  files:
62
106
  - ".gitignore"
63
107
  - ".rspec"
108
+ - ".rubocop.yml"
64
109
  - ".travis.yml"
110
+ - CHANGELOG.md
65
111
  - Gemfile
66
112
  - LICENSE.txt
67
113
  - README.md
@@ -69,12 +115,24 @@ files:
69
115
  - bin/console
70
116
  - bin/setup
71
117
  - lib/webauthn.rb
118
+ - lib/webauthn/attestation_statement.rb
119
+ - lib/webauthn/attestation_statement/base.rb
120
+ - lib/webauthn/attestation_statement/fido_u2f.rb
121
+ - lib/webauthn/attestation_statement/none.rb
122
+ - lib/webauthn/authenticator_attestation_response.rb
123
+ - lib/webauthn/authenticator_data.rb
124
+ - lib/webauthn/authenticator_data/attested_credential_data.rb
125
+ - lib/webauthn/authenticator_data/attested_credential_data/public_key_u2f.rb
126
+ - lib/webauthn/client_data.rb
72
127
  - lib/webauthn/version.rb
73
128
  - webauthn.gemspec
74
- homepage: https://github.com/cedarcode/webauthn
129
+ homepage: https://github.com/cedarcode/webauthn-ruby
75
130
  licenses:
76
131
  - MIT
77
- metadata: {}
132
+ metadata:
133
+ bug_tracker_uri: https://github.com/cedarcode/webauthn-ruby/issues
134
+ changelog_uri: https://github.com/cedarcode/webauthn-ruby/blob/master/CHANGELOG.md
135
+ source_code_uri: https://github.com/cedarcode/webauthn-ruby
78
136
  post_install_message:
79
137
  rdoc_options: []
80
138
  require_paths: