@@ -25,7 +25,7 @@ use config::Command;
2525use config:: { Config , Slot } ;
2626use configure:: DeviceModeConfig ;
2727use hmacmode:: Hmac ;
28- use manager:: { read_serial_from_device , Flags , Frame } ;
28+ use manager:: { Flags , Frame } ;
2929use otpmode:: Aes128Block ;
3030use rusb:: { Context , UsbContext } ;
3131use sec:: { crc16, CRC_RESIDUAL_OK } ;
@@ -58,12 +58,43 @@ impl Yubico {
5858 }
5959 }
6060
61+ pub fn read_serial_from_device ( & mut self , device : rusb:: Device < Context > ) -> Result < u32 > {
62+ // let mut context = Context::new()?;
63+ let mut handle =
64+ manager:: open_device ( & mut self . context , device. bus_number ( ) , device. address ( ) ) ?;
65+ let challenge = [ 0 ; 64 ] ;
66+ let command = Command :: DeviceSerial ;
67+
68+ let d = Frame :: new ( challenge, command) ; // FixMe: do not need a challange
69+ let mut buf = [ 0 ; 8 ] ;
70+ manager:: wait (
71+ & mut handle. 0 ,
72+ |f| !f. contains ( Flags :: SLOT_WRITE_FLAG ) ,
73+ & mut buf,
74+ ) ?;
75+
76+ manager:: write_frame ( & mut handle. 0 , & d) ?;
77+
78+ // Read the response.
79+ let mut response = [ 0 ; 36 ] ;
80+ manager:: read_response ( & mut handle. 0 , & mut response) ?;
81+
82+ // Check response.
83+ if crc16 ( & response[ ..6 ] ) != crate :: sec:: CRC_RESIDUAL_OK {
84+ return Err ( YubicoError :: WrongCRC ) ;
85+ }
86+
87+ let serial = structure ! ( "2I" ) . unpack ( response[ ..8 ] . to_vec ( ) ) ?;
88+
89+ Ok ( serial. 0 )
90+ }
91+
6192 pub fn find_yubikey ( & mut self ) -> Result < Yubikey > {
6293 for device in self . context . devices ( ) . unwrap ( ) . iter ( ) {
6394 let descr = device. device_descriptor ( ) . unwrap ( ) ;
6495 if descr. vendor_id ( ) == VENDOR_ID {
6596 let name = device. open ( ) ?. read_product_string_ascii ( & descr) ?;
66- let serial = read_serial_from_device ( & mut self . context . clone ( ) , device. clone ( ) ) ?;
97+ let serial = self . read_serial_from_device ( device. clone ( ) ) ?;
6798 let yubikey = Yubikey {
6899 name : name,
69100 serial : serial,
@@ -86,7 +117,7 @@ impl Yubico {
86117 let descr = device. device_descriptor ( ) . unwrap ( ) ;
87118 if descr. vendor_id ( ) == VENDOR_ID {
88119 let name = device. open ( ) ?. read_product_string_ascii ( & descr) ?;
89- let serial = read_serial_from_device ( & mut self . context . clone ( ) , device. clone ( ) ) ?;
120+ let serial = self . read_serial_from_device ( device. clone ( ) ) ?;
90121 let yubikey = Yubikey {
91122 name : name,
92123 serial : serial,
0 commit comments