diff --git a/src/lib.rs b/src/lib.rs
index 367deb8..71bc454 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -25,7 +25,7 @@ use config::Command;
 use config::{Config, Slot};
 use configure::DeviceModeConfig;
 use hmacmode::Hmac;
-use manager::{Flags, Frame};
+use manager::{read_serial_from_device, Flags, Frame};
 use otpmode::Aes128Block;
 use rusb::{Context, UsbContext};
 use sec::{crc16, CRC_RESIDUAL_OK};
@@ -39,6 +39,7 @@ type Result<T> = ::std::result::Result<T, YubicoError>;
 #[derive(Clone, Debug, PartialEq)]
 pub struct Yubikey {
     pub name: String,
+    pub serial: u32,
     pub product_id: u16,
     pub vendor_id: u16,
     pub bus_id: u8,
@@ -61,13 +62,11 @@ impl Yubico {
         for device in self.context.devices().unwrap().iter() {
             let descr = device.device_descriptor().unwrap();
             if descr.vendor_id() == VENDOR_ID {
-                let name = device
-                    .open()
-                    .unwrap()
-                    .read_product_string_ascii(&descr)
-                    .unwrap();
+                let name = device.open()?.read_product_string_ascii(&descr)?;
+                let serial = read_serial_from_device(device.clone())?;
                 let yubikey = Yubikey {
                     name: name,
+                    serial: serial,
                     product_id: descr.product_id(),
                     vendor_id: descr.vendor_id(),
                     bus_id: device.bus_number(),
@@ -86,13 +85,11 @@ impl Yubico {
         for device in self.context.devices().unwrap().iter() {
             let descr = device.device_descriptor().unwrap();
             if descr.vendor_id() == VENDOR_ID {
-                let name = device
-                    .open()
-                    .unwrap()
-                    .read_product_string_ascii(&descr)
-                    .unwrap();
+                let name = device.open()?.read_product_string_ascii(&descr)?;
+                let serial = read_serial_from_device(device.clone())?;
                 let yubikey = Yubikey {
                     name: name,
+                    serial: serial,
                     product_id: descr.product_id(),
                     vendor_id: descr.vendor_id(),
                     bus_id: device.bus_number(),
@@ -117,7 +114,11 @@ impl Yubico {
         let d = device_config.to_frame(conf.command);
         let mut buf = [0; 8];
 
-        match manager::open_device(&mut self.context, conf.yubikey) {
+        match manager::open_device(
+            &mut self.context,
+            conf.yubikey.bus_id,
+            conf.yubikey.address_id,
+        ) {
             Ok((mut handle, interfaces)) => {
                 manager::wait(
                     &mut handle,
@@ -142,7 +143,11 @@ impl Yubico {
     }
 
     pub fn read_serial_number(&mut self, conf: Config) -> Result<u32> {
-        match manager::open_device(&mut self.context, conf.yubikey) {
+        match manager::open_device(
+            &mut self.context,
+            conf.yubikey.bus_id,
+            conf.yubikey.address_id,
+        ) {
             Ok((mut handle, interfaces)) => {
                 let challenge = [0; 64];
                 let command = Command::DeviceSerial;
@@ -178,7 +183,11 @@ impl Yubico {
     pub fn challenge_response_hmac(&mut self, chall: &[u8], conf: Config) -> Result<Hmac> {
         let mut hmac = Hmac([0; 20]);
 
-        match manager::open_device(&mut self.context, conf.yubikey) {
+        match manager::open_device(
+            &mut self.context,
+            conf.yubikey.bus_id,
+            conf.yubikey.address_id,
+        ) {
             Ok((mut handle, interfaces)) => {
                 let mut challenge = [0; 64];
 
@@ -225,7 +234,11 @@ impl Yubico {
             block: GenericArray::clone_from_slice(&[0; 16]),
         };
 
-        match manager::open_device(&mut self.context, conf.yubikey) {
+        match manager::open_device(
+            &mut self.context,
+            conf.yubikey.bus_id,
+            conf.yubikey.address_id,
+        ) {
             Ok((mut handle, interfaces)) => {
                 let mut challenge = [0; 64];
                 //(&mut challenge[..6]).copy_from_slice(chall);
diff --git a/src/manager.rs b/src/manager.rs
index b909109..f5f4b8d 100644
--- a/src/manager.rs
+++ b/src/manager.rs
@@ -1,12 +1,12 @@
 use crate::config::Command;
 use crate::sec::crc16;
 use crate::yubicoerror::YubicoError;
-use rusb::{request_type, Context, DeviceHandle, Direction, Recipient, RequestType, UsbContext};
+use rusb::{
+    request_type, Context, Device, DeviceHandle, Direction, Recipient, RequestType, UsbContext,
+};
 use std::time::Duration;
 use std::{slice, thread};
 
-use crate::Yubikey;
-
 const DATA_SIZE: usize = 64;
 const HID_GET_REPORT: u8 = 0x01;
 const HID_SET_REPORT: u8 = 0x09;
@@ -19,9 +19,40 @@ bitflags! {
     }
 }
 
+pub fn read_serial_from_device(device: Device<Context>) -> Result<u32, YubicoError> {
+    let mut context = Context::new()?;
+    let mut handle = open_device(&mut context, device.bus_number(), device.address())?;
+    let challenge = [0; 64];
+    let command = Command::DeviceSerial;
+
+    let d = Frame::new(challenge, command); // FixMe: do not need a challange
+    let mut buf = [0; 8];
+    wait(
+        &mut handle.0,
+        |f| !f.contains(Flags::SLOT_WRITE_FLAG),
+        &mut buf,
+    )?;
+
+    write_frame(&mut handle.0, &d)?;
+
+    // Read the response.
+    let mut response = [0; 36];
+    read_response(&mut handle.0, &mut response)?;
+
+    // Check response.
+    if crc16(&response[..6]) != crate::sec::CRC_RESIDUAL_OK {
+        return Err(YubicoError::WrongCRC);
+    }
+
+    let serial = structure!("2I").unpack(response[..8].to_vec())?;
+
+    Ok(serial.0)
+}
+
 pub fn open_device(
     context: &mut Context,
-    yubikey: Yubikey,
+    bus_id: u8,
+    address_id: u8,
 ) -> Result<(DeviceHandle<Context>, Vec<u8>), YubicoError> {
     let devices = match context.devices() {
         Ok(device) => device,
@@ -38,7 +69,7 @@ pub fn open_device(
             }
         };
 
-        if device.bus_number() == yubikey.bus_id && device.address() == yubikey.address_id {
+        if device.bus_number() == bus_id && device.address() == address_id {
             match device.open() {
                 Ok(mut handle) => {
                     let config = match device.config_descriptor(0) {