pub fn parse_version_nibbles(v: u32) -> Version
Expand description

Parses and integer with nibbles xxxx.yy.zz into a semver::Version.

Examples found in repository?
src/reader.rs (line 448)
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
    fn try_from(cd: CodeDirectoryBlob<'a>) -> Result<Self, Self::Error> {
        let mut temp = cd
            .slot_digests()
            .iter()
            .map(|(slot, digest)| (slot, digest.as_hex()))
            .collect::<Vec<_>>();
        temp.sort_by(|(a, _), (b, _)| a.cmp(b));

        let slot_digests = temp
            .into_iter()
            .map(|(slot, digest)| format!("{slot:?}: {digest}"))
            .collect::<Vec<_>>();

        Ok(Self {
            version: format!("0x{:X}", cd.version),
            flags: format!("{:?}", cd.flags),
            identifier: cd.ident.to_string(),
            team_name: cd.team_name.map(|x| x.to_string()),
            signed_entity_size: cd.code_limit as _,
            digest_type: format!("{}", cd.digest_type),
            platform: cd.platform,
            executable_segment_flags: cd.exec_seg_flags.map(|x| format!("{x:?}")),
            runtime_version: cd
                .runtime
                .map(|x| format!("{}", crate::macho::parse_version_nibbles(x))),
            code_digests_count: cd.code_digests.len(),
            slot_digests,
        })
    }
More examples
Hide additional examples
src/macho.rs (line 459)
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
    pub fn find_targeting(&self) -> Result<Option<MachoTarget>, AppleCodesignError> {
        let ctx = parse_magic_and_ctx(self.data, 0)?
            .1
            .expect("context should have been parsed before");

        for lc in &self.macho.load_commands {
            if lc.command.cmd() == LC_BUILD_VERSION {
                let build_version = self
                    .data
                    .pread_with::<BuildVersionCommand>(lc.offset, ctx.le)?;

                return Ok(Some(MachoTarget {
                    platform: build_version.platform.into(),
                    minimum_os_version: parse_version_nibbles(build_version.minos),
                    sdk_version: parse_version_nibbles(build_version.sdk),
                }));
            }
        }

        for lc in &self.macho.load_commands {
            let command = match lc.command {
                CommandVariant::VersionMinMacosx(c) => Some((c, Platform::MacOs)),
                CommandVariant::VersionMinIphoneos(c) => Some((c, Platform::IOs)),
                CommandVariant::VersionMinTvos(c) => Some((c, Platform::TvOs)),
                CommandVariant::VersionMinWatchos(c) => Some((c, Platform::WatchOs)),
                _ => None,
            };

            if let Some((command, platform)) = command {
                return Ok(Some(MachoTarget {
                    platform,
                    minimum_os_version: parse_version_nibbles(command.version),
                    sdk_version: parse_version_nibbles(command.sdk),
                }));
            }
        }

        Ok(None)
    }
src/signing_settings.rs (line 835)
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
    pub fn import_settings_from_macho(&mut self, data: &[u8]) -> Result<(), AppleCodesignError> {
        info!("inferring default signing settings from Mach-O binary");

        for macho in MachFile::parse(data)?.into_iter() {
            let index = macho.index.unwrap_or(0);

            let scope_main = SettingsScope::Main;
            let scope_index = SettingsScope::MultiArchIndex(index);
            let scope_arch = SettingsScope::MultiArchCpuType(macho.macho.header.cputype());

            // Older operating system versions don't have support for SHA-256 in
            // signatures. If the minimum version targeting in the binary doesn't
            // support SHA-256, we automatically change the digest targeting settings
            // so the binary will be signed correctly.
            if let Some(targeting) = macho.find_targeting()? {
                let sha256_version = targeting.platform.sha256_digest_support()?;

                if !sha256_version.matches(&targeting.minimum_os_version) {
                    info!(
                        "activating SHA-1 digests because minimum OS target {} is not {}",
                        targeting.minimum_os_version, sha256_version
                    );

                    // This logic is a bit wonky. We want SHA-1 to be present on all binaries
                    // within a fat binary. So if we need SHA-1 mode, we set the setting on the
                    // main scope and then clear any overrides on fat binary scopes so our
                    // settings are canonical.
                    self.set_digest_type(DigestType::Sha1);
                    self.add_extra_digest(scope_main.clone(), DigestType::Sha256);
                    self.extra_digests.remove(&scope_arch);
                    self.extra_digests.remove(&scope_index);
                }
            }

            // The Mach-O can have embedded Info.plist data. Use it if available and not
            // already defined in settings.
            if let Some(info_plist) = macho.embedded_info_plist()? {
                if self.info_plist_data(&scope_main).is_some()
                    || self.info_plist_data(&scope_index).is_some()
                    || self.info_plist_data(&scope_arch).is_some()
                {
                    info!("using Info.plist data from settings");
                } else {
                    info!("preserving Info.plist data already present in Mach-O");
                    self.set_info_plist_data(scope_index.clone(), info_plist);
                }
            }

            if let Some(sig) = macho.code_signature()? {
                if let Some(cd) = sig.code_directory()? {
                    if self.binary_identifier(&scope_main).is_some()
                        || self.binary_identifier(&scope_index).is_some()
                        || self.binary_identifier(&scope_arch).is_some()
                    {
                        info!("using binary identifier from settings");
                    } else {
                        info!("preserving existing binary identifier in Mach-O");
                        self.set_binary_identifier(scope_index.clone(), cd.ident);
                    }

                    if self.team_id.contains_key(&scope_main)
                        || self.team_id.contains_key(&scope_index)
                        || self.team_id.contains_key(&scope_arch)
                    {
                        info!("using team ID from settings");
                    } else if let Some(team_id) = cd.team_name {
                        info!("preserving team ID in existing Mach-O signature");
                        self.team_id
                            .insert(scope_index.clone(), team_id.to_string());
                    }

                    if self.code_signature_flags(&scope_main).is_some()
                        || self.code_signature_flags(&scope_index).is_some()
                        || self.code_signature_flags(&scope_arch).is_some()
                    {
                        info!("using code signature flags from settings");
                    } else if !cd.flags.is_empty() {
                        info!("preserving code signature flags in existing Mach-O signature");
                        self.set_code_signature_flags(scope_index.clone(), cd.flags);
                    }

                    if self.runtime_version(&scope_main).is_some()
                        || self.runtime_version(&scope_index).is_some()
                        || self.runtime_version(&scope_arch).is_some()
                    {
                        info!("using runtime version from settings");
                    } else if let Some(version) = cd.runtime {
                        info!("preserving runtime version in existing Mach-O signature");
                        self.set_runtime_version(
                            scope_index.clone(),
                            parse_version_nibbles(version),
                        );
                    }
                }

                if let Some(entitlements) = sig.entitlements()? {
                    if self.entitlements_plist(&scope_main).is_some()
                        || self.entitlements_plist(&scope_index).is_some()
                        || self.entitlements_plist(&scope_arch).is_some()
                    {
                        info!("using entitlements from settings");
                    } else {
                        info!("preserving existing entitlements in Mach-O");
                        self.set_entitlements_xml(
                            SettingsScope::MultiArchIndex(index),
                            entitlements.as_str(),
                        )?;
                    }
                }
            }
        }

        Ok(())
    }