pub(crate) fn extract(image: &[u8]) -> Result<Self, Error> {
        let complete_image = image;
        if image.len() > Self::MAX_RAW_LEN as usize {
            return Err(Error::parse_err(format!(
                "could not get application properties from binary image (image larger than limit of {} bytes)",
                Self::MAX_RAW_LEN
            )));
        }

        if let Some(pos) = image
            .windows(Self::MAGIC.len())
            .position(|win| win == Self::MAGIC)
        {
            if image.len() < pos + Self::LENGTH {
                return Err(Error::parse_err(
                    "could not get application properties from binary image (image too small)",
                ));
            }

            info!(
                "app properties at {:#X}: {:?}",
                pos,
                Blob(&image[pos..pos + Self::LENGTH])
            );

            let mut image = &image[pos + Self::MAGIC.len()..];
            let version = image.read_u32::<LittleEndian>()?;
            let (v_major, v_minor) = (version >> 8, version & 0xff);
            if v_major > Self::MAJOR_VERSION_SUPPORTED {
                return Err(Error::parse_err(format!(
                    "unsupported app property struct version {}.{} (expected {}.x)",
                    v_major,
                    v_minor,
                    Self::MAJOR_VERSION_SUPPORTED
                )));
            }

            let signature_type = image.read_u32::<LittleEndian>()?;
            let signature_location = image.read_u32::<LittleEndian>()?;
            let app_info = AppInfo::parse(&image[..AppInfo::LENGTH])?;

            let signature_type = SignatureType::from_u32(signature_type).ok_or_else(|| {
                Error::parse_err(format!(
                    "invalid signature type {} in app properties",
                    signature_type,
                ))
            })?;
            let signature_len = match signature_type {
                SignatureType::None => 0,
                SignatureType::Crc32 => {
                    // FIXME
                    return Err(Error::parse_err(r#"CRC-32 "signatures" not yet supported"#));
                }
                SignatureType::EcdsaP256 => 64,
            };
            if signature_location != 0 {
                if signature_location as usize + signature_len > complete_image.len() {
                    return Err(Error::parse_err(format!(
                        "invalid signature location {:#010X} (length is {} bytes, image length is {:#010X})",
                        signature_location,
                        signature_len,
                        complete_image.len(),
                    )));
                }

                if let SignatureType::None = signature_type {
                    return Err(Error::parse_err(format!(
                        "non-zero signature location {:#010X} but signature type 'None'",
                        signature_location,
                    )));
                }
            }

            let this = Self {
                position: pos as u32,
                version,
                signature_type,
                signature_location,
                app_info,
            };
            debug!("parsed app properties: {:?}", this);
            Ok(this)
        } else {
            Err(Error::parse_err(
                "could not find application info in binary image",
            ))
        }
    }
/// Extracts the application property structure from a raw app image.
Extracts the application property structure from a raw app image.
Extracts the application property structure from a raw app image .
pub(crate) fn extract(image: &[u8]) -> Result<Self, Error> {
        let complete_image = image;
        if image.len() > Self::MAX_RAW_LEN as usize {
            return Err(Error::parse_err(format!(
                "could not get application properties from binary image (image larger than limit of {} bytes)",
                Self::MAX_RAW_LEN
            )));
        }
        if let Some(pos) = image
            .windows(Self::MAGIC.len())
            .position(|win| win == Self::MAGIC)
        {
            if image.len() < pos + Self::LENGTH {
                return Err(Error::parse_err(
                    "could not get application properties from binary image (image too small)",
                ));
            }
            info!(
                "app properties at {:#X}: {:?}",
                pos,
                Blob(&image[pos..pos + Self::LENGTH])
            );
            let mut image = &image[pos + Self::MAGIC.len()..];
            let version = image.read_u32::<LittleEndian>()?;
            let (v_major, v_minor) = (version >> 8, version & 0xff);
            if v_major > Self::MAJOR_VERSION_SUPPORTED {
                return Err(Error::parse_err(format!(
                    "unsupported app property struct version {}.{} (expected {}.x)",
                    v_major,
                    v_minor,
                    Self::MAJOR_VERSION_SUPPORTED
                )));
            }
            let signature_type = image.read_u32::<LittleEndian>()?;
            let signature_location = image.read_u32::<LittleEndian>()?;
            let app_info = AppInfo::parse(&image[..AppInfo::LENGTH])?;
            let signature_type = SignatureType::from_u32(signature_type).ok_or_else(|| {
                Error::parse_err(format!(
                    "invalid signature type {} in app properties",
                    signature_type,
                ))
            })?;
            let signature_len = match signature_type {
                SignatureType::None => 0,
                SignatureType::Crc32 => {
                    // FIXME
                    return Err(Error::parse_err(r#"CRC-32 "signatures" not yet supported"#));
                }
                SignatureType::EcdsaP256 => 64,
            };
            if signature_location != 0 {
                if signature_location as usize + signature_len > complete_image.len() {
                    return Err(Error::parse_err(format!(
                        "invalid signature location {:#010X} (length is {} bytes, image length is {:#010X})",
                        signature_location,
                        signature_len,
                        complete_image.len(),
                    )));
                }
                if let SignatureType::None = signature_type {
                    return Err(Error::parse_err(format!(
                        "non-zero signature location {:#010X} but signature type 'None'",
                        signature_location,
                    )));
                }
            }
            let this = Self {
                position: pos as u32,
                version,
                signature_type,
                signature_location,
                app_info,
            };
            debug!("parsed app properties: {:?}", this);
            Ok(this)
        } else {
            Err(Error::parse_err(
                "could not find application info in binary image",
            ))
        }
    }
pub ( crate ) fn extract ( image : & [ u8 ] ) -> Result < Self , Error > { let complete_image = image ; if image . len ( ) > Self :: MAX_RAW_LEN as usize { return Err ( Error :: parse_err ( format ! ( " " Self MAX_RAW_LEN ) ) ) ; } if let Some ( pos ) = image . windows ( Self :: MAGIC . len ( ) ) . position ( | win | win == Self :: MAGIC ) { if image . len ( ) < pos + Self :: LENGTH { return Err ( Error :: parse_err ( " " , ) ) ; } info ! ( " " pos Blob ( image [ pos pos Self LENGTH ] ) ) ; let mut image = & image [ pos + Self :: MAGIC . len ( ) .. ] ; let version = image . read_u32 :: < LittleEndian > ( ) ? ; let ( v_major , v_minor ) = ( version >> 8 , version & 0xff ) ; if v_major > Self :: MAJOR_VERSION_SUPPORTED { return Err ( Error :: parse_err ( format ! ( " " v_major v_minor Self MAJOR_VERSION_SUPPORTED ) ) ) ; } let signature_type = image . read_u32 :: < LittleEndian > ( ) ? ; let signature_location = image . read_u32 :: < LittleEndian > ( ) ? ; let app_info = AppInfo :: parse ( & image [ .. AppInfo :: LENGTH ] ) ? ; let signature_type = SignatureType :: from_u32 ( signature_type ) . ok_or_else ( | | { Error :: parse_err ( format ! ( " " signature_type ) ) } ) ? ; let signature_len = match signature_type { SignatureType :: None => 0 , SignatureType :: Crc32 => { // FIXME return Err ( Error :: parse_err ( r#"CRC-32 "signatures" not yet supported"# ) ) ; } SignatureType :: EcdsaP256 => 64 , } ; if signature_location != 0 { if signature_location as usize + signature_len > complete_image . len ( ) { return Err ( Error :: parse_err ( format ! ( " " signature_location signature_len complete_image len ( ) ) ) ) ; } if let SignatureType :: None = signature_type { return Err ( Error :: parse_err ( format ! ( " " signature_location ) ) ) ; } } let this = Self { position : pos as u32 , version , signature_type , signature_location , app_info , } ; debug ! ( " " this ) ; Ok ( this ) } else { Err ( Error :: parse_err ( " " , ) ) } }
Extracts the application property structure from a raw app image.
Extracts the application property structure from a raw app image .
image
&[u8]