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

Code before:
                payload.len() - extended_apdu_lc - 3
            } else {
                0
            };
            if byte_0 == 0 && extended_apdu_le_len <= 3 {
                // If first byte is zero AND the next two bytes can be parsed as a big-endian
                // length that covers the rest of the block (plus few additional bytes for Le), we
                // have an extended-length APDU
                let last_byte: u32 = (*payload.last().unwrap()).into();
                return Ok(APDU {
                    header: array_ref!(header, 0, APDU_HEADER_LEN).into(),
                    lc: extended_apdu_lc as u16,
                    data: payload[3..(payload.len() - extended_apdu_le_len)].to_vec(),
                    le: match extended_apdu_le_len {
                        0 => 0,
                        1 => {
                            if last_byte == 0x00 {
                                0x100
                            } else {
                                last_byte
                            }
                        }
                        2 => {
                            let le_parsed = BigEndian::read_u16(&payload[payload.len() - 2..]);
                            if le_parsed == 0x00 {
                                0x100
                            } 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),

Review comment (suggestion):
If I'm correct, the value should be `0x10000`.
When `Le` is encoded on 2 or 3 bytes, a 0 is interpreted as 65 536.

Code after:
                payload.len() - extended_apdu_lc - 3
            } else {
                0
            };
            if byte_0 == 0 && extended_apdu_le_len <= 3 {
                // If first byte is zero AND the next two bytes can be parsed as a big-endian
                // length that covers the rest of the block (plus few additional bytes for Le), we
                // have an extended-length APDU
                let last_byte: u32 = (*payload.last().unwrap()).into();
                return Ok(APDU {
                    header: array_ref!(header, 0, APDU_HEADER_LEN).into(),
                    lc: extended_apdu_lc as u16,
                    data: payload[3..(payload.len() - extended_apdu_le_len)].to_vec(),
                    le: match extended_apdu_le_len {
                        0 => 0,
                        1 => {
                            if last_byte == 0x00 {
                                0x100
                            } else {
                                last_byte
                            }
                        }
                        2 => {
                            let le_parsed = BigEndian::read_u16(&payload[payload.len() - 2..]);
                            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),