1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
//! An implementation of an Ephemeral (in-memory) webauthn configuration provider //! This stores all challenges and credentials in memory - IE they are lost on //! service restart. It's only really useful for demo-sites, testing and as an //! example/reference implementation of the WebauthnConfig trait. use crate::WebauthnConfig; /// An implementation of an Ephemeral (in-memory) webauthn configuration provider /// This stores all challenges and credentials in memory - IE they are lost on /// service restart. It's only really useful for demo-sites, testing and as an /// example/reference implementation of the WebauthnConfig trait. pub struct WebauthnEphemeralConfig { rp_name: String, rp_id: String, rp_origin: String, } impl std::fmt::Debug for WebauthnEphemeralConfig { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( f, "WebauthnEphemeralConfig{{ rp_name: {:?}, rp_id: {:?}, rp_origin: {:?} }}", self.rp_name, self.rp_id, self.rp_origin ) } } impl WebauthnConfig for WebauthnEphemeralConfig { /// Returns the relying party name. See the trait documentation for more. fn get_relying_party_name(&self) -> String { self.rp_name.clone() } /// Returns the relying party id. See the trait documentation for more. fn get_relying_party_id(&self) -> String { self.rp_id.clone() } /// Retrieve the relying party origin. See the trait documentation for more. fn get_origin(&self) -> &String { &self.rp_origin } /* /// Persist a challenge associated to a userId. See the trait documentation for more. fn persist_challenge(&mut self, userid: UserId, challenge: Challenge) -> Result<(), ()> { self.chals.put(userid, challenge); Ok(()) } /// Retrieve a challenge associated to a userId. See the trait documentation for more. fn retrieve_challenge(&mut self, userid: &UserId) -> Option<Challenge> { self.chals.pop(userid) } /// Assert if a credential related to a userId exists. See the trait documentation for more. fn does_exist_credential(&self, userid: &UserId, cred: &Credential) -> Result<bool, ()> { match self.creds.get(userid) { Some(creds) => Ok(creds.contains_key(&cred.cred_id)), None => Ok(false), } } /// Persist a credential related to a userId. See the trait documentation for more. fn persist_credential(&mut self, userid: UserId, cred: Credential) -> Result<(), ()> { match self.creds.get_mut(&userid) { Some(v) => { let cred_id = cred.cred_id.clone(); v.insert(cred_id, cred); } None => { let mut t = BTreeMap::new(); let credential_id = cred.cred_id.clone(); t.insert(credential_id, cred); self.creds.insert(userid, t); } }; Ok(()) } /// Update a credentials counter. See the trait documentation for more. fn credential_update_counter( &mut self, userid: &UserId, cred: &Credential, counter: u32, ) -> Result<(), ()> { match self.creds.get_mut(userid) { Some(v) => { let cred_id = cred.cred_id.clone(); let _ = v.remove(&cred_id); let mut c = cred.clone(); c.counter = counter; v.insert(cred_id, c); Ok(()) } None => { // Invalid state but not end of world ... Err(()) } } } /// Report an invalid credential counter. See the trait documentation for more. fn credential_report_invalid_counter( &mut self, userid: &UserId, cred: &Credential, _counter: u32, ) -> Result<(), ()> { match self.creds.get_mut(userid) { Some(v) => { v.remove(&cred.cred_id); Ok(()) } None => { // Invalid state but not end of world ... Err(()) } } } /// Retrieve the credentials associated to a userId. See the trait documentation for more. fn retrieve_credentials(&self, userid: &UserId) -> Option<Vec<&Credential>> { match self.creds.get(userid) { Some(creds) => Some(creds.iter().map(|(_, v)| v).collect()), None => None, } } */ } impl WebauthnEphemeralConfig { /// Create a new Webauthn Ephemeral instance. This requires a provided relying party /// name, origin and id. See the trait documentation for more detail on relying party /// name, origin and id. pub fn new(rp_name: &str, rp_origin: &str, rp_id: &str) -> Self { WebauthnEphemeralConfig { rp_name: rp_name.to_string(), rp_id: rp_id.to_string(), rp_origin: rp_origin.to_string(), } } }