将 requirement 和 requirement 集合解析为其抽象语法树形式,然后评估它们。
Apple 为他们的代码签名需求语言提供了一个编译器,形式为 SecRequirementCreateWithString
,但没有公开解析器及其对应的抽象语法树。这个软件包正是如此。
虽然 Apple 提供了用于 SecRequirement
的评估器,形式为 SecStaticCodeCheckValidity
,但没有能力看到为什么验证失败。这个软件包提供了详细的解释。
为了查看应用程序是否以及如何满足其指定的 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)
Requirement 可以以 SecRequirement
s 的形式或 String
s 的形式提供。运行此示例输出
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
评估树的每个未被满足的叶节点都用上标数字注释。这些数字然后在底部用于提供解释,说明为什么叶节点未被满足。
请参阅此软件包的 DocC 文档以获取更多详细信息。
Apple 已经发布了几篇文档,以不同程度讨论他们的需求语言