Home

Awesome

Required

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

Apple provides a compiler for their Code Signing Requirement Language in the form of SecRequirementCreateWithString, but does not expose a parser and its corresponding abstract syntax tree. This package does precisely that.

While Apple does provide an evaluator for a SecRequirement in the form of SecStaticCodeCheckValidity, there is no ability to see why validation has failed. This package provides detailed explanations.

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: