+enum Kind : uint32_t {
+ exprForm = 1, // prefix expr form
+};
+
+enum ExprOp : uint32_t {
+ opFalse, // unconditionally false
+ opTrue, // unconditionally true
+ opIdent, // match canonical code [string]
+ opAppleAnchor, // signed by Apple as Apple's product
+ opAnchorHash, // match anchor [cert hash]
+ opInfoKeyValue, // *legacy* - use opInfoKeyField [key; value]
+ opAnd, // binary prefix expr AND expr [expr; expr]
+ opOr, // binary prefix expr OR expr [expr; expr]
+ opCDHash, // match hash of CodeDirectory directly [cd hash]
+ opNot, // logical inverse [expr]
+ opInfoKeyField, // Info.plist key field [string; match suffix]
+ opCertField, // Certificate field [cert index; field name; match suffix]
+ opTrustedCert, // require trust settings to approve one particular cert [cert index]
+ opTrustedCerts, // require trust settings to approve the cert chain
+ opCertGeneric, // Certificate component by OID [cert index; oid; match suffix]
+ opAppleGenericAnchor, // signed by Apple in any capacity
+ opEntitlementField, // entitlement dictionary field [string; match suffix]
+ opCertPolicy, // Certificate policy by OID [cert index; oid; match suffix]
+ opNamedAnchor, // named anchor type
+ opNamedCode, // named subroutine
+ opPlatform, // platform constraint [integer]
+ exprOpCount // (total opcode count in use)
+};
+
+enum MatchOperation {
+ matchExists, // anything but explicit "false" - no value stored
+ matchEqual, // equal (CFEqual)
+ matchContains, // partial match (substring)
+ matchBeginsWith, // partial match (initial substring)
+ matchEndsWith, // partial match (terminal substring)
+ matchLessThan, // less than (string with numeric comparison)
+ matchGreaterThan, // greater than (string with numeric comparison)
+ matchLessEqual, // less or equal (string with numeric comparison)
+ matchGreaterEqual, // greater or equal (string with numeric comparison)
+};
+
+#define OID_ISO_MEMBER 42
+#define OID_US OID_ISO_MEMBER, 134, 72
+#define APPLE_OID OID_US, 0x86, 0xf7, 0x63
+#define APPLE_ADS_OID APPLE_OID, 0x64
+#define APPLE_EXTENSION_OID APPLE_ADS_OID, 6
+
+
+struct Algorithm {
+ size_t size_;
+ uint8_t type_;
+
+ Algorithm(size_t size, uint8_t type) :
+ size_(size),
+ type_(type)
+ {
+ }
+
+ virtual const uint8_t *operator [](const ldid::Hash &hash) const = 0;
+
+ virtual void operator ()(uint8_t *hash, const void *data, size_t size) const = 0;
+ virtual void operator ()(ldid::Hash &hash, const void *data, size_t size) const = 0;
+ virtual void operator ()(std::vector<char> &hash, const void *data, size_t size) const = 0;
+
+ virtual const char *name() = 0;
+};
+
+struct AlgorithmSHA1 :
+ Algorithm
+{
+ AlgorithmSHA1() :
+ Algorithm(SHA_DIGEST_LENGTH, CS_HASHTYPE_SHA160_160)
+ {
+ }
+
+ virtual const uint8_t *operator [](const ldid::Hash &hash) const {
+ return hash.sha1_;
+ }
+
+ void operator ()(uint8_t *hash, const void *data, size_t size) const {
+ SHA1(static_cast<const uint8_t *>(data), size, hash);
+ }
+
+ void operator ()(ldid::Hash &hash, const void *data, size_t size) const {
+ return operator()(hash.sha1_, data, size);
+ }
+
+ void operator ()(std::vector<char> &hash, const void *data, size_t size) const {
+ hash.resize(SHA_DIGEST_LENGTH);
+ return operator ()(reinterpret_cast<uint8_t *>(hash.data()), data, size);
+ }
+
+ virtual const char *name() {
+ return "sha1";
+ }
+};
+
+struct AlgorithmSHA256 :
+ Algorithm
+{
+ AlgorithmSHA256() :
+ Algorithm(SHA256_DIGEST_LENGTH, CS_HASHTYPE_SHA256_256)
+ {
+ }
+
+ virtual const uint8_t *operator [](const ldid::Hash &hash) const {
+ return hash.sha256_;
+ }
+
+ void operator ()(uint8_t *hash, const void *data, size_t size) const {
+ SHA256(static_cast<const uint8_t *>(data), size, hash);
+ }
+
+ void operator ()(ldid::Hash &hash, const void *data, size_t size) const {
+ return operator()(hash.sha256_, data, size);
+ }
+
+ void operator ()(std::vector<char> &hash, const void *data, size_t size) const {
+ hash.resize(SHA256_DIGEST_LENGTH);
+ return operator ()(reinterpret_cast<uint8_t *>(hash.data()), data, size);
+ }
+
+ virtual const char *name() {
+ return "sha256";
+ }
+};
+
+static bool do_sha1(true);
+static bool do_sha256(true);
+
+static const std::vector<Algorithm *> &GetAlgorithms() {
+ static AlgorithmSHA1 sha1;
+ static AlgorithmSHA256 sha256;