pub(crate) unsafe fn _ykpiv_get_serial(
    state: *mut YubiKey,
    p_serial: *mut u32,
    f_force: bool,
) -> ErrorKind {
    let mut _currentBlock;
    let mut res;
    let yk_applet: *const u8 = ptr::null();
    let mut data = [0u8; 255];
    let mut recv_len = data.len() as u32;
    let mut sw: i32 = 0;
    let p_temp: *mut u8;

    if state.is_null() {
        return ErrorKind::ArgumentError;
    }

    if !f_force && (*state).serial != 0 {
        if !p_serial.is_null() {
            *p_serial = (*state).serial;
        }

        return ErrorKind::Ok;
    }

    if (*state).ver.major < 5 {
        // get serial from neo/yk4 devices using the otp applet
        let mut temp = [0u8; 255];
        recv_len = temp.len() as u32;

        let mut apdu = APDU::default();
        apdu.ins = YKPIV_INS_SELECT_APPLICATION;
        apdu.p1 = 0x04;
        apdu.lc = mem::size_of_val(&yk_applet) as u8;

        memcpy(
            apdu.data.as_mut_ptr() as *mut c_void,
            yk_applet as *const c_void,
            mem::size_of_val(&yk_applet),
        );

        res = _send_data(state, &mut apdu, temp.as_mut_ptr(), &mut recv_len, &mut sw);

        if res != ErrorKind::Ok {
            if (*state).verbose != 0 {
                eprintln!(
                    "Failed communicating with card: \'{}\'",
                    ykpiv_strerror(res)
                );
            }

            return res;
        }

        if sw != SW_SUCCESS {
            if (*state).verbose != 0 {
                eprintln!("Failed selecting yk application: {:04x}", sw);
            }

            return ErrorKind::GenericError;
        }

        recv_len = temp.len() as u32;
        apdu = APDU::default();
        apdu.ins = 0x01;
        apdu.p1 = 0x10;
        apdu.lc = 0x00;

        res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw);

        if res != ErrorKind::Ok {
            if (*state).verbose != 0 {
                eprintln!(
                    "Failed communicating with card: \'{}\'",
                    ykpiv_strerror(res)
                );
            }

            return res;
        }

        if sw != SW_SUCCESS {
            if (*state).verbose != 0 {
                eprintln!("Failed retrieving serial number: {:04x}", sw);
            }

            return ErrorKind::GenericError;
        }

        recv_len = temp.len() as u32;
        apdu = APDU::default();
        apdu.ins = YKPIV_INS_SELECT_APPLICATION;
        apdu.p1 = 0x04;
        apdu.lc = mem::size_of_val(&AID) as u8;

        memcpy(
            apdu.data.as_mut_ptr() as *mut c_void,
            AID.as_ptr() as *const c_void,
            mem::size_of_val(&AID),
        );

        res = _send_data(state, &mut apdu, temp.as_mut_ptr(), &mut recv_len, &mut sw);

        if res != ErrorKind::Ok {
            if (*state).verbose != 0 {
                eprintln!(
                    "Failed communicating with card: \'{}\'",
                    ykpiv_strerror(res)
                );
            }
            return res;
        }

        if sw != SW_SUCCESS {
            if (*state).verbose != 0 {
                eprintln!("Failed selecting application: {:04x}", sw);
            }
            return ErrorKind::GenericError;
        }

        _currentBlock = 17;
    } else {
        // get serial from yk5 and later devices using the f8 command
        let mut apdu = APDU::default();
        apdu.ins = YKPIV_INS_GET_SERIAL;

        res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw);

        if res != ErrorKind::Ok {
            if (*state).verbose != 0 {
                eprintln!(
                    "Failed communicating with card: \'{}\'",
                    ykpiv_strerror(res)
                );
            }
            return res;
        } else if sw != SW_SUCCESS {
            if (*state).verbose != 0 {
                eprintln!("Failed retrieving serial number: {:04x}", sw);
            }
            return ErrorKind::GenericError;
        }
        _currentBlock = 17;
    }

    if _currentBlock == 17 {
        // check that we received enough data for the serial number
        if recv_len < 4 {
            return ErrorKind::SizeError;
        }

        // TODO(tarcieri): replace pointers and casts with proper references!
        #[allow(trivial_casts)]
        {
            p_temp = &mut (*state).serial as (*mut u32) as (*mut u8);
        }

        *p_temp = data[3];
        *p_temp.add(1) = data[2];
        *p_temp.add(2) = data[1];
        *p_temp.add(3) = data[0];

        if !p_serial.is_null() {
            *p_serial = (*state).serial;
        }
    }

    res
}
/// Get YubiKey device serial number
///
/// NOTE: caller must make sure that this is wrapped in a transaction for synchronized operation
Get YubiKey device serial number
NOTE: caller must make sure that this is wrapped in a transaction for synchronized operation
Get YubiKey device serial number NOTE : caller must make sure that this is wrapped in a transaction for synchronized operation
pub(crate) unsafe fn _ykpiv_get_serial(
    state: *mut YubiKey,
    p_serial: *mut u32,
    f_force: bool,
) -> ErrorKind {
    let mut _currentBlock;
    let mut res;
    let yk_applet: *const u8 = ptr::null();
    let mut data = [0u8; 255];
    let mut recv_len = data.len() as u32;
    let mut sw: i32 = 0;
    let p_temp: *mut u8;
    if state.is_null() {
        return ErrorKind::ArgumentError;
    }
    if !f_force && (*state).serial != 0 {
        if !p_serial.is_null() {
            *p_serial = (*state).serial;
        }
        return ErrorKind::Ok;
    }
    if (*state).ver.major < 5 {
        // get serial from neo/yk4 devices using the otp applet
        let mut temp = [0u8; 255];
        recv_len = temp.len() as u32;
        let mut apdu = APDU::default();
        apdu.ins = YKPIV_INS_SELECT_APPLICATION;
        apdu.p1 = 0x04;
        apdu.lc = mem::size_of_val(&yk_applet) as u8;
        memcpy(
            apdu.data.as_mut_ptr() as *mut c_void,
            yk_applet as *const c_void,
            mem::size_of_val(&yk_applet),
        );
        res = _send_data(state, &mut apdu, temp.as_mut_ptr(), &mut recv_len, &mut sw);
        if res != ErrorKind::Ok {
            if (*state).verbose != 0 {
                eprintln!(
                    "Failed communicating with card: \'{}\'",
                    ykpiv_strerror(res)
                );
            }
            return res;
        }
        if sw != SW_SUCCESS {
            if (*state).verbose != 0 {
                eprintln!("Failed selecting yk application: {:04x}", sw);
            }
            return ErrorKind::GenericError;
        }
        recv_len = temp.len() as u32;
        apdu = APDU::default();
        apdu.ins = 0x01;
        apdu.p1 = 0x10;
        apdu.lc = 0x00;
        res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw);
        if res != ErrorKind::Ok {
            if (*state).verbose != 0 {
                eprintln!(
                    "Failed communicating with card: \'{}\'",
                    ykpiv_strerror(res)
                );
            }
            return res;
        }
        if sw != SW_SUCCESS {
            if (*state).verbose != 0 {
                eprintln!("Failed retrieving serial number: {:04x}", sw);
            }
            return ErrorKind::GenericError;
        }
        recv_len = temp.len() as u32;
        apdu = APDU::default();
        apdu.ins = YKPIV_INS_SELECT_APPLICATION;
        apdu.p1 = 0x04;
        apdu.lc = mem::size_of_val(&AID) as u8;
        memcpy(
            apdu.data.as_mut_ptr() as *mut c_void,
            AID.as_ptr() as *const c_void,
            mem::size_of_val(&AID),
        );
        res = _send_data(state, &mut apdu, temp.as_mut_ptr(), &mut recv_len, &mut sw);
        if res != ErrorKind::Ok {
            if (*state).verbose != 0 {
                eprintln!(
                    "Failed communicating with card: \'{}\'",
                    ykpiv_strerror(res)
                );
            }
            return res;
        }
        if sw != SW_SUCCESS {
            if (*state).verbose != 0 {
                eprintln!("Failed selecting application: {:04x}", sw);
            }
            return ErrorKind::GenericError;
        }
        _currentBlock = 17;
    } else {
        // get serial from yk5 and later devices using the f8 command
        let mut apdu = APDU::default();
        apdu.ins = YKPIV_INS_GET_SERIAL;
        res = _send_data(state, &mut apdu, data.as_mut_ptr(), &mut recv_len, &mut sw);
        if res != ErrorKind::Ok {
            if (*state).verbose != 0 {
                eprintln!(
                    "Failed communicating with card: \'{}\'",
                    ykpiv_strerror(res)
                );
            }
            return res;
        } else if sw != SW_SUCCESS {
            if (*state).verbose != 0 {
                eprintln!("Failed retrieving serial number: {:04x}", sw);
            }
            return ErrorKind::GenericError;
        }
        _currentBlock = 17;
    }
    if _currentBlock == 17 {
        // check that we received enough data for the serial number
        if recv_len < 4 {
            return ErrorKind::SizeError;
        }
        // TODO(tarcieri): replace pointers and casts with proper references!
        #[allow(trivial_casts)]
        {
            p_temp = &mut (*state).serial as (*mut u32) as (*mut u8);
        }
        *p_temp = data[3];
        *p_temp.add(1) = data[2];
        *p_temp.add(2) = data[1];
        *p_temp.add(3) = data[0];
        if !p_serial.is_null() {
            *p_serial = (*state).serial;
        }
    }
    res
}
pub ( crate ) unsafe fn _ykpiv_get_serial ( state : * mut YubiKey , p_serial : * mut u32 , f_force : bool , ) -> ErrorKind { let mut _currentBlock ; let mut res ; let yk_applet : * const u8 = ptr :: null ( ) ; let mut data = [ 0u8 ; 255 ] ; let mut recv_len = data . len ( ) as u32 ; let mut sw : i32 = 0 ; let p_temp : * mut u8 ; if state . is_null ( ) { return ErrorKind :: ArgumentError ; } if ! f_force && ( * state ) . serial != 0 { if ! p_serial . is_null ( ) { * p_serial = ( * state ) . serial ; } return ErrorKind :: Ok ; } if ( * state ) . ver . major < 5 { // get serial from neo/yk4 devices using the otp applet let mut temp = [ 0u8 ; 255 ] ; recv_len = temp . len ( ) as u32 ; let mut apdu = APDU :: default ( ) ; apdu . ins = YKPIV_INS_SELECT_APPLICATION ; apdu . p1 = 0x04 ; apdu . lc = mem :: size_of_val ( & yk_applet ) as u8 ; memcpy ( apdu . data . as_mut_ptr ( ) as * mut c_void , yk_applet as * const c_void , mem :: size_of_val ( & yk_applet ) , ) ; res = _send_data ( state , & mut apdu , temp . as_mut_ptr ( ) , & mut recv_len , & mut sw ) ; if res != ErrorKind :: Ok { if ( * state ) . verbose != 0 { eprintln ! ( " \' \' " ykpiv_strerror ( res ) ) ; } return res ; } if sw != SW_SUCCESS { if ( * state ) . verbose != 0 { eprintln ! ( " " sw ) ; } return ErrorKind :: GenericError ; } recv_len = temp . len ( ) as u32 ; apdu = APDU :: default ( ) ; apdu . ins = 0x01 ; apdu . p1 = 0x10 ; apdu . lc = 0x00 ; res = _send_data ( state , & mut apdu , data . as_mut_ptr ( ) , & mut recv_len , & mut sw ) ; if res != ErrorKind :: Ok { if ( * state ) . verbose != 0 { eprintln ! ( " \' \' " ykpiv_strerror ( res ) ) ; } return res ; } if sw != SW_SUCCESS { if ( * state ) . verbose != 0 { eprintln ! ( " " sw ) ; } return ErrorKind :: GenericError ; } recv_len = temp . len ( ) as u32 ; apdu = APDU :: default ( ) ; apdu . ins = YKPIV_INS_SELECT_APPLICATION ; apdu . p1 = 0x04 ; apdu . lc = mem :: size_of_val ( & AID ) as u8 ; memcpy ( apdu . data . as_mut_ptr ( ) as * mut c_void , AID . as_ptr ( ) as * const c_void , mem :: size_of_val ( & AID ) , ) ; res = _send_data ( state , & mut apdu , temp . as_mut_ptr ( ) , & mut recv_len , & mut sw ) ; if res != ErrorKind :: Ok { if ( * state ) . verbose != 0 { eprintln ! ( " \' \' " ykpiv_strerror ( res ) ) ; } return res ; } if sw != SW_SUCCESS { if ( * state ) . verbose != 0 { eprintln ! ( " " sw ) ; } return ErrorKind :: GenericError ; } _currentBlock = 17 ; } else { // get serial from yk5 and later devices using the f8 command let mut apdu = APDU :: default ( ) ; apdu . ins = YKPIV_INS_GET_SERIAL ; res = _send_data ( state , & mut apdu , data . as_mut_ptr ( ) , & mut recv_len , & mut sw ) ; if res != ErrorKind :: Ok { if ( * state ) . verbose != 0 { eprintln ! ( " \' \' " ykpiv_strerror ( res ) ) ; } return res ; } else if sw != SW_SUCCESS { if ( * state ) . verbose != 0 { eprintln ! ( " " sw ) ; } return ErrorKind :: GenericError ; } _currentBlock = 17 ; } if _currentBlock == 17 { // check that we received enough data for the serial number if recv_len < 4 { return ErrorKind :: SizeError ; } // TODO(tarcieri): replace pointers and casts with proper references! # [ allow ( trivial_casts ) ] { p_temp = & mut ( * state ) . serial as ( * mut u32 ) as ( * mut u8 ) ; } * p_temp = data [ 3 ] ; * p_temp . add ( 1 ) = data [ 2 ] ; * p_temp . add ( 2 ) = data [ 1 ] ; * p_temp . add ( 3 ) = data [ 0 ] ; if ! p_serial . is_null ( ) { * p_serial = ( * state ) . serial ; } } res }
Get YubiKey device serial number
NOTE: caller must make sure that this is wrapped in a transaction for synchronized operation
Get YubiKey device serial number NOTE : caller must make sure that this is wrapped in a transaction for synchronized operation
state
*mut YubiKey
p_serial
*mut u32
f_force
bool