Contents

trilemma-dev/required

Parse requirement and requirement sets into their abstract syntax tree form and then evaluate them.

Example

To see whether and how an application satisfies its designated requirement:

// Retrieve the designated requirement for Numbers
let url = URL(fileURLWithPath: "/Applications/Numbers.app")
var code: SecStaticCode?
SecStaticCodeCreateWithPath(url as CFURL, [], &code)
var requirement: SecRequirement?
SecCodeCopyDesignatedRequirement(code!, [], &requirement)

// See whether and how Numbers satisifies its designated requirement
let abstractRequirement = try Parser.parse(requirement: requirement!)
let evaluation = try abstractRequirement.evaluateForStaticCode(code!)
print("Does \(url.lastPathComponent) satisfy its designated requirement?")
print(evaluation.isSatisfied ? "Yes" : "No")
print("\nEvaluation tree:")
print(evaluation.prettyDescription)

Requirements can be provided either as SecRequirements as shown in the above code snippet or as Strings. Running this example outputs:

Does Numbers.app satisfy its designated requirement?
Yes

Evaluation tree:
and {true}
|--() {true}
|  \--or {true}
|     |--and {true}
|     |  |--anchor apple generic {true}
|     |  \--certificate leaf[field.1.2.840.113635.100.6.1.9] {true}
|     \--and {false}
|        |--and {false}
|        |  |--and {false}
|        |  |  |--anchor apple generic {true}
|        |  |  \--certificate 1[field.1.2.840.113635.100.6.2.6] {false
|        |  \--certificate leaf[field.1.2.840.113635.100.6.1.13] {false
|        \--certificate leaf[subject.OU] = K36BKF7T3D {false
\--identifier "com.apple.iWork.Numbers" {true}

Constraints not satisfied:
1. The certificate <Apple Worldwide Developer Relations Certification Authority> does not contain OID 1.2.840.113635.100.6.2.6
2. The certificate <Apple Mac OS Application Signing> does not contain OID 1.2.840.113635.100.6.1.13
3. The certificate <Apple Mac OS Application Signing> does not contain element subject.OU

Each leaf node of the evaluation tree which was not satisfied is annotated with a superscript number. Those numbers are then used at the bottom to provide explanations for why the leaf node was not satified.

See this package's DocC documentation for more details.

Apple Resources

Apple has published several documents that discuss to varying degrees their requirements language:

Package Metadata

Repository: trilemma-dev/required

Default branch: main

README: README.md