examples-features/ctap: Fully implement HmacKeyCredential

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
diff --git a/examples-features/ctap.rs b/examples-features/ctap.rs
index a6d2d57..76cb829 100644
--- a/examples-features/ctap.rs
+++ b/examples-features/ctap.rs
@@ -43,25 +43,43 @@
     fn wink(&mut self) {}
 
     fn cancel(&mut self) {
+        println!("cancel");
         unimplemented!()
     }
 
     fn keepalive_needed(&mut self) -> KeepaliveResponse {
+        println!("keepalive_needed");
         unimplemented!()
     }
 
     fn start_timer(&mut self) {
-        unimplemented!()
+        println!("start_timer");
     }
 
     fn has_timed_out(&mut self) -> bool {
-        unimplemented!()
+        println!("has_timed_out");
+        false
     }
 }
 
 #[derive(Clone, Copy)]
 pub struct HmacKeyCredential(pub(crate) [u8; 40]);
 
+impl HmacKeyCredential {
+    fn new(mac: &[u8; 32], nonce: [u8; 8]) -> Self {
+        let mut new = [0; 40];
+        new[..32].copy_from_slice(&mac[..]);
+        new[32..].copy_from_slice(&nonce[..]);
+        Self(new)
+    }
+
+    fn get_mac(&self) -> [u8; 32] {
+        let mut mac = [0; 32];
+        mac.copy_from_slice(&self.0[..32]);
+        mac
+    }
+}
+
 impl AsRef<[u8]> for HmacKeyCredential {
     fn as_ref(&self) -> &[u8] {
         &self.0
@@ -104,6 +122,16 @@
         }
     }
 
+    pub(crate) fn push(&mut self, credential: HmacKeyCredential, counter: u32) -> Result<(), ()> {
+        if self.length < ITERATOR_MAX_LENGTH {
+            self.list[self.length] = Some((credential, counter));
+            self.length += 1;
+            Ok(())
+        } else {
+            Err(())
+        }
+    }
+
     pub(crate) fn len(&self) -> usize {
         self.length
     }