pub fn derive_designated_requirements(
    cert: &CapturedX509Certificate,
    identifier: Option<String>
) -> Result<Option<CodeRequirementExpression<'static>>, AppleCodesignError>
Expand description

Derive a designated requirements expression given a code signing certificate.

This function figures out what the run-time requirements of a signed binary should be given its code signing certificate.

We determine the flavor of Apple code signing certificate in use and apply an appropriate requirements policy. We strive for behavior equivalence with Apple’s codesign tool.

Examples found in repository?
src/macho_signing.rs (line 619)
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
    pub fn create_special_blobs(
        &self,
        settings: &SigningSettings,
        is_executable: bool,
    ) -> Result<Vec<(CodeSigningSlot, BlobData<'static>)>, AppleCodesignError> {
        let mut res = Vec::new();

        let mut requirements = CodeRequirements::default();

        match settings.designated_requirement(SettingsScope::Main) {
            DesignatedRequirementMode::Auto => {
                // If we are using an Apple-issued cert, this should automatically
                // derive appropriate designated requirements.
                if let Some((_, cert)) = settings.signing_key() {
                    info!("attempting to derive code requirements from signing certificate");
                    let identifier = Some(
                        settings
                            .binary_identifier(SettingsScope::Main)
                            .ok_or(AppleCodesignError::NoIdentifier)?
                            .to_string(),
                    );

                    if let Some(expr) = derive_designated_requirements(cert, identifier)? {
                        requirements.push(expr);
                    }
                }
            }
            DesignatedRequirementMode::Explicit(exprs) => {
                info!("using provided code requirements");
                for expr in exprs {
                    requirements.push(CodeRequirementExpression::from_bytes(expr)?.0);
                }
            }
        }

        // Always emit a RequirementSet blob, even if empty. Without it, validation fails
        // with `the sealed resource directory is invalid`.
        let mut blob = RequirementSetBlob::default();

        if !requirements.is_empty() {
            info!("code requirements: {}", requirements);
            requirements.add_to_requirement_set(&mut blob, RequirementType::Designated)?;
        }

        res.push((CodeSigningSlot::RequirementSet, blob.into()));

        if let Some(entitlements) = settings.entitlements_xml(SettingsScope::Main)? {
            info!("adding entitlements XML");
            let blob = EntitlementsBlob::from_string(&entitlements);

            res.push((CodeSigningSlot::Entitlements, blob.into()));
        }

        // The DER encoded entitlements weren't always present in the signature. The feature
        // appears to have been introduced in macOS 10.14 and is the default behavior as of
        // macOS 12 "when signing for all platforms." `codesign` appears to add the DER
        // representation whenever entitlements are present, but only if the current binary is
        // an executable (.filetype == MH_EXECUTE).
        if is_executable {
            if let Some(value) = settings.entitlements_plist(SettingsScope::Main) {
                info!("adding entitlements DER");
                let blob = EntitlementsDerBlob::from_plist(value)?;

                res.push((CodeSigningSlot::EntitlementsDer, blob.into()));
            }
        }

        Ok(res)
    }