|
1 | | -use super::get_info::AuthenticatorInfo; |
| 1 | +use super::get_info::{AuthenticatorInfo, AuthenticatorVersion}; |
2 | 2 | use super::{ |
3 | 3 | Command, CommandError, PinUvAuthCommand, RequestCtap1, RequestCtap2, Retryable, StatusCode, |
4 | 4 | }; |
@@ -300,18 +300,31 @@ impl MakeCredentials { |
300 | 300 | } |
301 | 301 | } |
302 | 302 |
|
303 | | - pub fn finalize_result<Dev: FidoDevice>(&self, _dev: &Dev, result: &mut MakeCredentialsResult) { |
| 303 | + pub fn finalize_result<Dev: FidoDevice>(&self, dev: &Dev, result: &mut MakeCredentialsResult) { |
| 304 | + let maybe_info = dev.get_authenticator_info(); |
| 305 | + |
304 | 306 | // Handle extensions whose outputs are not encoded in the authenticator data. |
305 | 307 | // 1. credProps |
306 | 308 | // "set clientExtensionResults["credProps"]["rk"] to the value of the |
307 | 309 | // requireResidentKey parameter that was used in the invocation of the |
308 | 310 | // authenticatorMakeCredential operation." |
309 | | - if self.extensions.cred_props == Some(true) { |
| 311 | + // Note: a CTAP 2.0 authenticator is allowed to create a discoverable credential even |
| 312 | + // if one was not requested, so there is a case in which we cannot confidently |
| 313 | + // return `rk=false` here. We omit the response entirely in this case. |
| 314 | + let dev_supports_rk = maybe_info.map_or(false, |info| info.options.resident_key); |
| 315 | + let requested_rk = self.options.resident_key.unwrap_or(false); |
| 316 | + let max_supported_version = maybe_info.map_or(AuthenticatorVersion::U2F_V2, |info| { |
| 317 | + info.max_supported_version() |
| 318 | + }); |
| 319 | + let rk_uncertain = max_supported_version == AuthenticatorVersion::FIDO_2_0 |
| 320 | + && dev_supports_rk |
| 321 | + && !requested_rk; |
| 322 | + if self.extensions.cred_props == Some(true) && !rk_uncertain { |
310 | 323 | result |
311 | 324 | .extensions |
312 | 325 | .cred_props |
313 | 326 | .get_or_insert(Default::default()) |
314 | | - .rk = self.options.resident_key.unwrap_or(false); |
| 327 | + .rk = requested_rk; |
315 | 328 | } |
316 | 329 |
|
317 | 330 | // 2. hmac-secret |
|
0 commit comments