webauthn 1.14.0 → 1.15.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 +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +37 -24
- data/lib/android_safetynet/attestation_response.rb +4 -13
- data/lib/webauthn.rb +3 -43
- data/lib/webauthn/attestation_statement.rb +0 -7
- data/lib/webauthn/attestation_statement/android_key.rb +1 -0
- data/lib/webauthn/attestation_statement/base.rb +8 -0
- data/lib/webauthn/attestation_statement/tpm/cert_info.rb +2 -0
- data/lib/webauthn/attestation_statement/tpm/pub_area.rb +3 -1
- data/lib/webauthn/authenticator_assertion_response.rb +2 -1
- data/lib/webauthn/authenticator_attestation_response.rb +1 -1
- data/lib/webauthn/authenticator_response.rb +10 -2
- data/lib/webauthn/client_data.rb +1 -0
- data/lib/webauthn/configuration.rb +17 -0
- data/lib/webauthn/credential_creation_options.rb +60 -0
- data/lib/webauthn/credential_entity.rb +11 -0
- data/lib/webauthn/credential_options.rb +13 -0
- data/lib/webauthn/credential_request_options.rb +19 -0
- data/lib/webauthn/credential_rp_entity.rb +8 -0
- data/lib/webauthn/credential_user_entity.rb +16 -0
- data/lib/webauthn/fake_authenticator.rb +7 -3
- data/lib/webauthn/fake_authenticator/authenticator_data.rb +6 -4
- data/lib/webauthn/fake_client.rb +1 -0
- data/lib/webauthn/signature_verifier.rb +3 -0
- data/lib/webauthn/version.rb +1 -1
- data/webauthn.gemspec +4 -3
- metadata +15 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ac8a0cc80530217e636ae8c83128363f9f9e725243cb40f5dad4e0941db4149f
|
4
|
+
data.tar.gz: b781f8035cf6c25626b6da8e0ced92838d5d6f5defcecc7180f826af4184540d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '01449706124d9e42b81c4691075e1de5f6192651a9cb8f798c2b78bb31ef0171d9ece8ef09412b73cbdb3444f38e963455439a5d1cf9eb781c8804e713dd5002'
|
7
|
+
data.tar.gz: 4f5c370130707a529566f4be6887c592c600674caf5f2b198d9329de9b7de3098ec775cc222400d2ab8fe214310058b1b8563b769cc006089ddc1f2910526187
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v1.15.0] - 2019-05-16
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- Ability to configure Origin, RP ID and RP Name via `WebAuthn.configure`
|
8
|
+
|
3
9
|
## [v1.14.0] - 2019-04-25
|
4
10
|
|
5
11
|
### Added
|
@@ -173,6 +179,7 @@ Note: Both additions should help making it compatible with Chrome for Android 70
|
|
173
179
|
- `WebAuthn::AuthenticatorAttestationResponse.valid?` can be used to validate fido-u2f attestations returned by the browser
|
174
180
|
- Works with ruby 2.5
|
175
181
|
|
182
|
+
[v1.15.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.14.0...v1.15.0/
|
176
183
|
[v1.14.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.13.0...v1.14.0/
|
177
184
|
[v1.13.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.12.0...v1.13.0/
|
178
185
|
[v1.12.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.11.0...v1.12.0/
|
data/README.md
CHANGED
@@ -1,17 +1,23 @@
|
|
1
|
-
# WebAuthn ruby library :key:
|
1
|
+
# WebAuthn ruby server library :key:
|
2
2
|
|
3
|
-
|
3
|
+
Makes your Ruby/Rails web server become a functional [WebAuthn Relying Party](https://www.w3.org/TR/webauthn/#webauthn-relying-party).
|
4
|
+
|
5
|
+
Takes care of the [server-side operations](https://www.w3.org/TR/webauthn/#rp-operations) needed to
|
6
|
+
[register](https://www.w3.org/TR/webauthn/#registration) or [authenticate](https://www.w3.org/TR/webauthn/#authentication)
|
7
|
+
a user [credential](https://www.w3.org/TR/webauthn/#public-key-credential), including the necessary cryptographic checks.
|
4
8
|
|
5
9
|
[](https://rubygems.org/gems/webauthn)
|
6
10
|
[](https://travis-ci.org/cedarcode/webauthn-ruby)
|
7
11
|
[](https://gitter.im/cedarcode/webauthn-ruby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
8
12
|
|
13
|
+
## Why WebAuthn in my web server?
|
14
|
+
|
15
|
+
- [Security Benefits for WebAuthn Relying Parties](https://www.w3.org/TR/webauthn/#sctn-rp-benefits)
|
16
|
+
|
9
17
|
## What is WebAuthn?
|
10
18
|
|
11
19
|
WebAuthn (Web Authentication) is a W3C standard for secure public-key authentication on the Web supported by all leading browsers and platforms.
|
12
20
|
|
13
|
-
For more:
|
14
|
-
|
15
21
|
- WebAuthn [W3C Recommendation](https://www.w3.org/TR/webauthn/) (i.e. "The Standard")
|
16
22
|
- WebAuthn [intro](https://www.yubico.com/webauthn/) by Yubico
|
17
23
|
- WebAuthn [article](https://en.wikipedia.org/wiki/WebAuthn) in Wikipedia
|
@@ -22,7 +28,7 @@ For more:
|
|
22
28
|
|
23
29
|
This ruby library will help your Ruby/Rails server act as a conforming [_Relying-Party_](https://www.w3.org/TR/webauthn/#relying-party), in WebAuthn terminology. But for the [_Registration_](https://www.w3.org/TR/webauthn/#registration) and [_Authentication_](https://www.w3.org/TR/webauthn/#authentication) ceremonies to fully work, you will also need to add two more pieces to the puzzle, a conforming [User Agent](https://www.w3.org/TR/webauthn/#conforming-user-agents) + [Authenticator](https://www.w3.org/TR/webauthn/#conforming-authenticators) pair.
|
24
30
|
|
25
|
-
|
31
|
+
Known conformant pairs are, for example:
|
26
32
|
|
27
33
|
- Google Chrome for Android 70+ and Android's Fingerprint-based platform authenticator
|
28
34
|
- Microsoft Edge and Windows 10 platform authenticator
|
@@ -54,6 +60,30 @@ Or install it yourself as:
|
|
54
60
|
|
55
61
|
NOTE: You can find a working example on how to use this gem in a __Rails__ app in [webauthn-rails-demo-app](https://github.com/cedarcode/webauthn-rails-demo-app).
|
56
62
|
|
63
|
+
### Configuration
|
64
|
+
|
65
|
+
For a Rails application this would go in `config/initializers/webauthn.rb`.
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
WebAuthn.configure do |config|
|
69
|
+
# This value needs to match `window.location.origin` evaluated by
|
70
|
+
# the User Agent during registration and authentication ceremonies.
|
71
|
+
config.origin = "https://auth.example.com"
|
72
|
+
|
73
|
+
# Relying Party name for display purposes
|
74
|
+
config.rp_name = "Example Inc."
|
75
|
+
|
76
|
+
# You can optionally specify a different Relying Party ID
|
77
|
+
# (https://www.w3.org/TR/webauthn/#relying-party-identifier)
|
78
|
+
# if it differs from the default one.
|
79
|
+
#
|
80
|
+
# In this case the default would be "auth.example.com", but you can set it to
|
81
|
+
# the suffix "example.com"
|
82
|
+
#
|
83
|
+
# config.rp_id = "example.com"
|
84
|
+
end
|
85
|
+
```
|
86
|
+
|
57
87
|
### Registration
|
58
88
|
|
59
89
|
#### Initiation phase
|
@@ -91,17 +121,9 @@ attestation_response = WebAuthn::AuthenticatorAttestationResponse.new(
|
|
91
121
|
client_data_json: client_data_json
|
92
122
|
)
|
93
123
|
|
94
|
-
# This value needs to match `window.location.origin` evaluated by
|
95
|
-
# the User Agent as part of the verification phase.
|
96
|
-
expected_origin = "https://www.example.com"
|
97
|
-
|
98
|
-
# In the case that a Relying Party ID (https://www.w3.org/TR/webauthn/#relying-party-identifier) different from `expected_origin` was used on
|
99
|
-
# `navigator.credentials.create`, it needs to specified for verification.
|
100
|
-
# Otherwise, you can ignore passing in this value to the `verify` method below.
|
101
|
-
rp_id = "example.com"
|
102
124
|
|
103
125
|
begin
|
104
|
-
attestation_response.verify(expected_challenge
|
126
|
+
attestation_response.verify(expected_challenge)
|
105
127
|
|
106
128
|
# 1. Register the new user and
|
107
129
|
# 2. Keep Credential ID and Credential Public Key under storage
|
@@ -158,15 +180,6 @@ assertion_response = WebAuthn::AuthenticatorAssertionResponse.new(
|
|
158
180
|
signature: signature
|
159
181
|
)
|
160
182
|
|
161
|
-
# This value needs to match `window.location.origin` evaluated by
|
162
|
-
# the User Agent as part of the verification phase.
|
163
|
-
expected_origin = "https://www.example.com"
|
164
|
-
|
165
|
-
# In the case that a Relying Party ID (https://www.w3.org/TR/webauthn/#relying-party-identifier) different from `expected_origin` was used on
|
166
|
-
# `navigator.credentials.get`, it needs to be specified for verification.
|
167
|
-
# Otherwise, you can ignore passing in this value to the `verify` method below.`
|
168
|
-
rp_id = "example.com"
|
169
|
-
|
170
183
|
# This hash must have the id and its corresponding public key of the
|
171
184
|
# previously stored credential for the user that is attempting to sign in.
|
172
185
|
allowed_credential = {
|
@@ -175,7 +188,7 @@ allowed_credential = {
|
|
175
188
|
}
|
176
189
|
|
177
190
|
begin
|
178
|
-
assertion_response.verify(expected_challenge,
|
191
|
+
assertion_response.verify(expected_challenge, allowed_credentials: [allowed_credential])
|
179
192
|
|
180
193
|
# Sign in the user
|
181
194
|
rescue WebAuthn::VerificationError => e
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "base64"
|
3
4
|
require "jwt"
|
5
|
+
require "webauthn/security_utils"
|
4
6
|
|
5
7
|
module AndroidSafetynet
|
6
8
|
# Decoupled from WebAuthn, candidate for extraction
|
@@ -46,7 +48,7 @@ module AndroidSafetynet
|
|
46
48
|
private
|
47
49
|
|
48
50
|
def valid_nonce?(nonce)
|
49
|
-
payload["nonce"]
|
51
|
+
WebAuthn::SecurityUtils.secure_compare(payload["nonce"], nonce)
|
50
52
|
end
|
51
53
|
|
52
54
|
def valid_attestation_domain?
|
@@ -58,22 +60,11 @@ module AndroidSafetynet
|
|
58
60
|
end
|
59
61
|
|
60
62
|
def valid_signature?
|
61
|
-
JWT.decode(response, leaf_certificate.public_key, true, algorithms:
|
63
|
+
JWT.decode(response, leaf_certificate.public_key, true, algorithms: ["ES256", "RS256"])
|
62
64
|
rescue JWT::VerificationError
|
63
65
|
false
|
64
66
|
end
|
65
67
|
|
66
|
-
def algorithm_for(public_key)
|
67
|
-
case public_key
|
68
|
-
when OpenSSL::PKey::RSA
|
69
|
-
"RS256"
|
70
|
-
when OpenSSL::PKey::EC, OpenSSL::PKey::EC::Point
|
71
|
-
"ES256"
|
72
|
-
else
|
73
|
-
raise "Unsupported algorithm"
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
68
|
def leaf_certificate
|
78
69
|
certificate_chain[0]
|
79
70
|
end
|
data/lib/webauthn.rb
CHANGED
@@ -1,48 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "cose/algorithm"
|
4
3
|
require "webauthn/authenticator_attestation_response"
|
5
4
|
require "webauthn/authenticator_assertion_response"
|
6
|
-
require "webauthn/
|
5
|
+
require "webauthn/configuration"
|
6
|
+
require "webauthn/credential_creation_options"
|
7
|
+
require "webauthn/credential_request_options"
|
7
8
|
require "webauthn/version"
|
8
|
-
|
9
|
-
require "base64"
|
10
|
-
require "securerandom"
|
11
|
-
require "json"
|
12
|
-
|
13
|
-
module WebAuthn
|
14
|
-
DEFAULT_ALGORITHMS = ["ES256", "RS256"].freeze
|
15
|
-
|
16
|
-
DEFAULT_PUB_KEY_CRED_PARAMS = DEFAULT_ALGORITHMS.map do |alg_name|
|
17
|
-
{ type: "public-key", alg: COSE::Algorithm.by_name(alg_name).id }
|
18
|
-
end.freeze
|
19
|
-
|
20
|
-
TYPES = { create: "webauthn.create", get: "webauthn.get" }.freeze
|
21
|
-
|
22
|
-
# TODO: make keyword arguments mandatory in next major version
|
23
|
-
def self.credential_creation_options(
|
24
|
-
rp_name: "web-server",
|
25
|
-
user_name: "web-user",
|
26
|
-
display_name: "web-user",
|
27
|
-
user_id: "1"
|
28
|
-
)
|
29
|
-
{
|
30
|
-
challenge: challenge,
|
31
|
-
pubKeyCredParams: DEFAULT_PUB_KEY_CRED_PARAMS,
|
32
|
-
rp: { name: rp_name },
|
33
|
-
user: { name: user_name, displayName: display_name, id: user_id }
|
34
|
-
}
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.credential_request_options
|
38
|
-
{
|
39
|
-
challenge: challenge,
|
40
|
-
allowCredentials: []
|
41
|
-
}
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.challenge
|
45
|
-
SecureRandom.random_bytes(32)
|
46
|
-
end
|
47
|
-
private_class_method :challenge
|
48
|
-
end
|
@@ -13,13 +13,6 @@ module WebAuthn
|
|
13
13
|
ATTESTATION_FORMAT_ANDROID_KEY = "android-key"
|
14
14
|
ATTESTATION_FORMAT_TPM = "tpm"
|
15
15
|
|
16
|
-
ATTESTATION_TYPE_NONE = "None"
|
17
|
-
ATTESTATION_TYPE_BASIC = "Basic"
|
18
|
-
ATTESTATION_TYPE_SELF = "Self"
|
19
|
-
ATTESTATION_TYPE_ATTCA = "AttCA"
|
20
|
-
ATTESTATION_TYPE_ECDAA = "ECDAA"
|
21
|
-
ATTESTATION_TYPE_BASIC_OR_ATTCA = "Basic_or_AttCA"
|
22
|
-
|
23
16
|
def self.from(format, statement)
|
24
17
|
case format
|
25
18
|
when ATTESTATION_FORMAT_NONE
|
@@ -1,10 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "openssl"
|
4
|
+
require "webauthn/authenticator_data/attested_credential_data"
|
4
5
|
require "webauthn/error"
|
5
6
|
|
6
7
|
module WebAuthn
|
7
8
|
module AttestationStatement
|
9
|
+
ATTESTATION_TYPE_NONE = "None"
|
10
|
+
ATTESTATION_TYPE_BASIC = "Basic"
|
11
|
+
ATTESTATION_TYPE_SELF = "Self"
|
12
|
+
ATTESTATION_TYPE_ATTCA = "AttCA"
|
13
|
+
ATTESTATION_TYPE_ECDAA = "ECDAA"
|
14
|
+
ATTESTATION_TYPE_BASIC_OR_ATTCA = "Basic_or_AttCA"
|
15
|
+
|
8
16
|
class Base
|
9
17
|
class NotSupportedError < Error; end
|
10
18
|
|
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "cose/algorithm"
|
3
4
|
require "cose/key"
|
4
5
|
require "tpm/constants"
|
5
6
|
require "tpm/t_public"
|
7
|
+
require "webauthn/attestation_statement/base"
|
6
8
|
|
7
9
|
module WebAuthn
|
8
10
|
module AttestationStatement
|
@@ -19,7 +21,7 @@ module WebAuthn
|
|
19
21
|
}.freeze
|
20
22
|
|
21
23
|
COSE_TO_TPM_CURVE = {
|
22
|
-
COSE::Key::
|
24
|
+
COSE::Key::Curve.by_name("P-256").id => ::TPM::ECC_NIST_P256
|
23
25
|
}.freeze
|
24
26
|
|
25
27
|
def initialize(data)
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require "cose/algorithm"
|
4
4
|
require "cose/key"
|
5
5
|
require "webauthn/attestation_statement/fido_u2f/public_key"
|
6
|
+
require "webauthn/authenticator_data"
|
6
7
|
require "webauthn/authenticator_response"
|
7
8
|
require "webauthn/signature_verifier"
|
8
9
|
|
@@ -19,7 +20,7 @@ module WebAuthn
|
|
19
20
|
@signature = signature
|
20
21
|
end
|
21
22
|
|
22
|
-
def verify(expected_challenge, expected_origin, allowed_credentials:, rp_id: nil)
|
23
|
+
def verify(expected_challenge, expected_origin = nil, allowed_credentials:, rp_id: nil)
|
23
24
|
super(expected_challenge, expected_origin, rp_id: rp_id)
|
24
25
|
|
25
26
|
verify_item(:credential, allowed_credentials)
|
@@ -1,8 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "base64"
|
4
|
+
require "webauthn/client_data"
|
3
5
|
require "webauthn/error"
|
6
|
+
require "webauthn/security_utils"
|
4
7
|
|
5
8
|
module WebAuthn
|
9
|
+
TYPES = { create: "webauthn.create", get: "webauthn.get" }.freeze
|
10
|
+
|
6
11
|
class VerificationError < Error; end
|
7
12
|
|
8
13
|
class AuthenticatorDataVerificationError < VerificationError; end
|
@@ -18,7 +23,10 @@ module WebAuthn
|
|
18
23
|
@client_data_json = client_data_json
|
19
24
|
end
|
20
25
|
|
21
|
-
def verify(expected_challenge, expected_origin, rp_id: nil)
|
26
|
+
def verify(expected_challenge, expected_origin = nil, rp_id: nil)
|
27
|
+
expected_origin ||= WebAuthn.configuration.origin || raise("Unspecified expected origin")
|
28
|
+
rp_id ||= WebAuthn.configuration.rp_id
|
29
|
+
|
22
30
|
verify_item(:type)
|
23
31
|
verify_item(:token_binding)
|
24
32
|
verify_item(:challenge, expected_challenge)
|
@@ -67,7 +75,7 @@ module WebAuthn
|
|
67
75
|
end
|
68
76
|
|
69
77
|
def valid_origin?(expected_origin)
|
70
|
-
client_data.origin == expected_origin
|
78
|
+
expected_origin && (client_data.origin == expected_origin)
|
71
79
|
end
|
72
80
|
|
73
81
|
def valid_rp_id?(rp_id)
|
data/lib/webauthn/client_data.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module WebAuthn
|
4
|
+
def self.configuration
|
5
|
+
@configuration ||= Configuration.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.configure
|
9
|
+
yield(configuration)
|
10
|
+
end
|
11
|
+
|
12
|
+
class Configuration
|
13
|
+
attr_accessor :origin
|
14
|
+
attr_accessor :rp_id
|
15
|
+
attr_accessor :rp_name
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cose/algorithm"
|
4
|
+
require "webauthn/credential_options"
|
5
|
+
require "webauthn/credential_rp_entity"
|
6
|
+
require "webauthn/credential_user_entity"
|
7
|
+
|
8
|
+
module WebAuthn
|
9
|
+
# TODO: make keyword arguments mandatory in next major version
|
10
|
+
def self.credential_creation_options(rp_name: nil, user_name: "web-user", display_name: "web-user", user_id: "1")
|
11
|
+
CredentialCreationOptions.new(
|
12
|
+
rp_name: rp_name, user_id: user_id, user_name: user_name, user_display_name: display_name
|
13
|
+
).to_h
|
14
|
+
end
|
15
|
+
|
16
|
+
class CredentialCreationOptions < CredentialOptions
|
17
|
+
DEFAULT_ALGORITHMS = ["ES256", "RS256"].freeze
|
18
|
+
DEFAULT_RP_NAME = "web-server"
|
19
|
+
|
20
|
+
DEFAULT_PUB_KEY_CRED_PARAMS = DEFAULT_ALGORITHMS.map do |alg_name|
|
21
|
+
{ type: "public-key", alg: COSE::Algorithm.by_name(alg_name).id }
|
22
|
+
end.freeze
|
23
|
+
|
24
|
+
def initialize(user_id:, user_name:, user_display_name: nil, rp_name: nil)
|
25
|
+
@user_id = user_id
|
26
|
+
@user_name = user_name
|
27
|
+
@user_display_name = user_display_name
|
28
|
+
@rp_name = rp_name
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_h
|
32
|
+
{
|
33
|
+
challenge: challenge,
|
34
|
+
pubKeyCredParams: pub_key_cred_params,
|
35
|
+
user: { id: user.id, name: user.name, displayName: user.display_name },
|
36
|
+
rp: { name: rp.name }
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def pub_key_cred_params
|
41
|
+
DEFAULT_PUB_KEY_CRED_PARAMS
|
42
|
+
end
|
43
|
+
|
44
|
+
def rp
|
45
|
+
@rp ||= CredentialRPEntity.new(name: rp_name || configuration.rp_name || DEFAULT_RP_NAME)
|
46
|
+
end
|
47
|
+
|
48
|
+
def user
|
49
|
+
@user ||= CredentialUserEntity.new(id: user_id, name: user_name, display_name: user_display_name)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
attr_reader :user_id, :user_name, :user_display_name, :rp_name
|
55
|
+
|
56
|
+
def configuration
|
57
|
+
WebAuthn.configuration
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "webauthn/credential_options"
|
4
|
+
|
5
|
+
module WebAuthn
|
6
|
+
def self.credential_request_options
|
7
|
+
CredentialRequestOptions.new.to_h
|
8
|
+
end
|
9
|
+
|
10
|
+
class CredentialRequestOptions < CredentialOptions
|
11
|
+
def to_h
|
12
|
+
{ challenge: challenge, allowCredentials: allow_credentials }
|
13
|
+
end
|
14
|
+
|
15
|
+
def allow_credentials
|
16
|
+
[]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "webauthn/credential_entity"
|
4
|
+
|
5
|
+
module WebAuthn
|
6
|
+
class CredentialUserEntity < CredentialEntity
|
7
|
+
attr_reader :id, :display_name
|
8
|
+
|
9
|
+
def initialize(id:, display_name: nil, **keyword_arguments)
|
10
|
+
super(**keyword_arguments)
|
11
|
+
|
12
|
+
@id = id
|
13
|
+
@display_name = display_name || name
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -8,8 +8,6 @@ require "webauthn/fake_authenticator/authenticator_data"
|
|
8
8
|
|
9
9
|
module WebAuthn
|
10
10
|
class FakeAuthenticator
|
11
|
-
AAGUID = SecureRandom.random_bytes(16)
|
12
|
-
|
13
11
|
def initialize
|
14
12
|
@credentials = {}
|
15
13
|
end
|
@@ -32,7 +30,13 @@ module WebAuthn
|
|
32
30
|
attestation_object
|
33
31
|
end
|
34
32
|
|
35
|
-
def get_assertion(
|
33
|
+
def get_assertion(
|
34
|
+
rp_id:,
|
35
|
+
client_data_hash:,
|
36
|
+
user_present: true,
|
37
|
+
user_verified: false,
|
38
|
+
aaguid: AuthenticatorData::AAGUID
|
39
|
+
)
|
36
40
|
credential_options = credentials[rp_id]
|
37
41
|
|
38
42
|
if credential_options
|
@@ -7,8 +7,10 @@ require "securerandom"
|
|
7
7
|
module WebAuthn
|
8
8
|
class FakeAuthenticator
|
9
9
|
class AuthenticatorData
|
10
|
+
AAGUID = SecureRandom.random_bytes(16)
|
11
|
+
|
10
12
|
def initialize(rp_id_hash:, credential: nil, sign_count: 0, user_present: true, user_verified: !user_present,
|
11
|
-
aaguid:
|
13
|
+
aaguid: AAGUID)
|
12
14
|
@rp_id_hash = rp_id_hash
|
13
15
|
@credential = credential
|
14
16
|
@sign_count = sign_count
|
@@ -100,9 +102,9 @@ module WebAuthn
|
|
100
102
|
key.instance_variable_set(:@alg, -257)
|
101
103
|
when OpenSSL::PKey::EC::Point
|
102
104
|
alg = {
|
103
|
-
COSE::Key::
|
104
|
-
COSE::Key::
|
105
|
-
COSE::Key::
|
105
|
+
COSE::Key::Curve.by_name("P-256").id => -7,
|
106
|
+
COSE::Key::Curve.by_name("P-384").id => -35,
|
107
|
+
COSE::Key::Curve.by_name("P-521").id => -36
|
106
108
|
}
|
107
109
|
|
108
110
|
key = COSE::Key::EC2.from_pkey(credential[:public_key])
|
data/lib/webauthn/fake_client.rb
CHANGED
data/lib/webauthn/version.rb
CHANGED
data/webauthn.gemspec
CHANGED
@@ -10,8 +10,9 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.authors = ["Gonzalo Rodriguez", "Braulio Martinez"]
|
11
11
|
spec.email = ["gonzalo@cedarcode.com", "braulio@cedarcode.com"]
|
12
12
|
|
13
|
-
spec.summary = "WebAuthn ruby library"
|
14
|
-
spec.description =
|
13
|
+
spec.summary = "WebAuthn ruby server library"
|
14
|
+
spec.description = 'WebAuthn ruby server library ― Make your application a W3C Web Authentication conformant
|
15
|
+
Relying Party and allow your users to authenticate with U2F and FIDO 2.0 authenticators.'
|
15
16
|
spec.homepage = "https://github.com/cedarcode/webauthn-ruby"
|
16
17
|
spec.license = "MIT"
|
17
18
|
|
@@ -32,7 +33,7 @@ Gem::Specification.new do |spec|
|
|
32
33
|
|
33
34
|
spec.add_dependency "bindata", "~> 2.4"
|
34
35
|
spec.add_dependency "cbor", "~> 0.5.9"
|
35
|
-
spec.add_dependency "cose", "~> 0.
|
36
|
+
spec.add_dependency "cose", "~> 0.7.0"
|
36
37
|
spec.add_dependency "jwt", [">= 1.5", "< 3.0"]
|
37
38
|
spec.add_dependency "openssl", "~> 2.0"
|
38
39
|
spec.add_dependency "securecompare", "~> 1.0"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: webauthn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gonzalo Rodriguez
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-
|
12
|
+
date: 2019-05-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bindata
|
@@ -45,14 +45,14 @@ dependencies:
|
|
45
45
|
requirements:
|
46
46
|
- - "~>"
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: 0.
|
48
|
+
version: 0.7.0
|
49
49
|
type: :runtime
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
53
|
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: 0.
|
55
|
+
version: 0.7.0
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: jwt
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -191,8 +191,9 @@ dependencies:
|
|
191
191
|
- - '='
|
192
192
|
- !ruby/object:Gem::Version
|
193
193
|
version: 0.67.2
|
194
|
-
description:
|
195
|
-
|
194
|
+
description: |-
|
195
|
+
WebAuthn ruby server library ― Make your application a W3C Web Authentication conformant
|
196
|
+
Relying Party and allow your users to authenticate with U2F and FIDO 2.0 authenticators.
|
196
197
|
email:
|
197
198
|
- gonzalo@cedarcode.com
|
198
199
|
- braulio@cedarcode.com
|
@@ -243,6 +244,13 @@ files:
|
|
243
244
|
- lib/webauthn/authenticator_data/attested_credential_data.rb
|
244
245
|
- lib/webauthn/authenticator_response.rb
|
245
246
|
- lib/webauthn/client_data.rb
|
247
|
+
- lib/webauthn/configuration.rb
|
248
|
+
- lib/webauthn/credential_creation_options.rb
|
249
|
+
- lib/webauthn/credential_entity.rb
|
250
|
+
- lib/webauthn/credential_options.rb
|
251
|
+
- lib/webauthn/credential_request_options.rb
|
252
|
+
- lib/webauthn/credential_rp_entity.rb
|
253
|
+
- lib/webauthn/credential_user_entity.rb
|
246
254
|
- lib/webauthn/error.rb
|
247
255
|
- lib/webauthn/fake_authenticator.rb
|
248
256
|
- lib/webauthn/fake_authenticator/attestation_object.rb
|
@@ -277,5 +285,5 @@ requirements: []
|
|
277
285
|
rubygems_version: 3.0.3
|
278
286
|
signing_key:
|
279
287
|
specification_version: 4
|
280
|
-
summary: WebAuthn ruby library
|
288
|
+
summary: WebAuthn ruby server library
|
281
289
|
test_files: []
|