@@ -98,9 +98,23 @@ impl MakeCredentialsResponseUnsignedExtensions {
9898 // https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#op-makecred-step-rk
9999 // if the "rk" option is false: the authenticator MUST create a non-discoverable credential.
100100 // Note: This step is a change from CTAP2.0 where if the "rk" option is false the authenticator could optionally create a discoverable credential.
101- Some ( CredentialPropsExtension {
102- rk : Some ( request. require_resident_key ) ,
103- } )
101+ match request. resident_key {
102+ Some ( ResidentKeyRequirement :: Discouraged ) | None => {
103+ Some ( CredentialPropsExtension { rk : Some ( false ) } )
104+ }
105+ Some ( ResidentKeyRequirement :: Preferred ) => {
106+ if info. map ( |i| i. option_enabled ( "rk" ) ) . unwrap_or_default ( ) {
107+ Some ( CredentialPropsExtension { rk : Some ( true ) } )
108+ } else {
109+ // Default value in case "rk" is missing (which it is in this constellation) is "false"
110+ // https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#makecred-rk
111+ Some ( CredentialPropsExtension { rk : Some ( false ) } )
112+ }
113+ }
114+ Some ( ResidentKeyRequirement :: Required ) => {
115+ Some ( CredentialPropsExtension { rk : Some ( true ) } )
116+ }
117+ }
104118 } else {
105119 Some ( CredentialPropsExtension {
106120 // For CTAP 2.0, we can't say if "rk" is true or not.
@@ -135,6 +149,13 @@ impl MakeCredentialsResponseUnsignedExtensions {
135149 }
136150}
137151
152+ #[ derive( Debug , Clone , Copy ) ]
153+ pub enum ResidentKeyRequirement {
154+ Required ,
155+ Preferred ,
156+ Discouraged ,
157+ }
158+
138159#[ derive( Debug , Clone ) ]
139160pub struct MakeCredentialRequest {
140161 pub hash : Vec < u8 > ,
@@ -143,7 +164,7 @@ pub struct MakeCredentialRequest {
143164 pub relying_party : Ctap2PublicKeyCredentialRpEntity ,
144165 /// userEntity
145166 pub user : Ctap2PublicKeyCredentialUserEntity ,
146- pub require_resident_key : bool ,
167+ pub resident_key : Option < ResidentKeyRequirement > ,
147168 pub user_verification : UserVerificationRequirement ,
148169 /// credTypesAndPubKeyAlgs
149170 pub algorithms : Vec < Ctap2CredentialType > ,
@@ -270,7 +291,7 @@ impl MakeCredentialRequest {
270291 exclude : None ,
271292 extensions : None ,
272293 origin : "example.org" . to_owned ( ) ,
273- require_resident_key : false ,
294+ resident_key : None ,
274295 user_verification : UserVerificationRequirement :: Discouraged ,
275296 timeout : Duration :: from_secs ( 10 ) ,
276297 }
@@ -294,7 +315,10 @@ impl DowngradableRequest<RegisterRequest> for MakeCredentialRequest {
294315 }
295316
296317 // Options must not include "rk" set to true.
297- if self . require_resident_key {
318+ if matches ! (
319+ self . resident_key,
320+ Some ( ResidentKeyRequirement :: Required )
321+ ) {
298322 debug ! ( "Not downgradable: request requires resident key" ) ;
299323 return false ;
300324 }
0 commit comments