Repository: google/OpenSK
File: src/ctap/apdu.rs (Rust)

Code before:
                                if last_byte == 0x00 {
                                    0x100
                                } else {
                                    last_byte
                                }
                            }
                            2 => BigEndian::read_u16(
                                &payload[payload.len() - extended_apdu_le_len..],
                            ) as u32,
                            3 => BigEndian::read_u32(
                                &payload[payload.len() - extended_apdu_le_len..],
                            ),
                            _ => 0,
                        },
                        case_type: ApduType::Extended(match extended_apdu_le_len {
                            0 => Case::Lc3Data,
                            1 => Case::Lc3DataLe1,
                            2 => Case::Lc3DataLe2,
                            3 => Case::Le3,
                            _ => Case::Unknown,
                        }),
                    });
                }
            }
        }
        return Err(ApduStatusCode::SW_COND_USE_NOT_SATISFIED);
    }
}

#[cfg(test)]
mod test {
    use super::*;

    fn pass_frame(frame: &[u8]) -> Result<APDU, ApduStatusCode> {
        APDU::try_from(frame)
    }

    #[test]
    fn test_case_type_1() {
        let frame: [u8; 4] = [0x00, 0x12, 0x00, 0x80];
        let response = pass_frame(&frame);
        assert!(response.is_ok());
        let expected = APDU {
            header: ApduHeader {
                cla: 0x00,
                ins: 0x12,
                p1: 0x00,
                p2: 0x80,
            },
            lc: 0x00,
            data: Vec::new(),

Review comment (security):
This error in the context of CTAP means that the authenticator is waiting for user presence.
I would put something else.

Code after:
                            if le_parsed == 0x00 {
                                0x10000
                            } else {
                                le_parsed as u32
                            }
                        }
                        3 => {
                            let le_first_byte: u32 =
                                (*payload.get(payload.len() - 3).unwrap()).into();
                            if le_first_byte != 0x00 {
                                return Err(ApduStatusCode::SW_INTERNAL_EXCEPTION);
                            }
                            let le_parsed = BigEndian::read_u16(&payload[payload.len() - 2..]);
                            if le_parsed == 0x00 {
                                0x10000
                            } else {
                                le_parsed as u32
                            }
                        }
                        _ => return Err(ApduStatusCode::SW_INTERNAL_EXCEPTION),
                    },
                    case_type: ApduType::Extended(match extended_apdu_le_len {
                        0 => Case::Lc3Data,
                        1 => Case::Lc3DataLe1,
                        2 => Case::Lc3DataLe2,
                        3 => Case::Le3,
                        _ => return Err(ApduStatusCode::SW_INTERNAL_EXCEPTION),
                    }),
                });
            }
        }

        return Err(ApduStatusCode::SW_INTERNAL_EXCEPTION);
    }
}

#[cfg(test)]
mod test {
    use super::*;

    fn pass_frame(frame: &[u8]) -> Result<APDU, ApduStatusCode> {
        APDU::try_from(frame)
    }

    #[test]
    fn test_case_type_1() {
        let frame: [u8; 4] = [0x00, 0x12, 0x00, 0x80];
        let response = pass_frame(&frame);
        assert!(response.is_ok());
        let expected = APDU {
            header: ApduHeader {