Function apple_codesign::derive_designated_requirements
source · 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)
}