X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/5c19dc3ae3bd8e40a9c028b0deddd50ff337692c..0d4552ce43ff8bf2e8666a9c5c44c3590eb117a8:/OSX/libsecurity_codesigning/lib/RequirementParser.cpp diff --git a/OSX/libsecurity_codesigning/lib/RequirementParser.cpp b/OSX/libsecurity_codesigning/lib/RequirementParser.cpp index dfaa3450..28b891eb 100644 --- a/OSX/libsecurity_codesigning/lib/RequirementParser.cpp +++ b/OSX/libsecurity_codesigning/lib/RequirementParser.cpp @@ -7,12 +7,26 @@ #include "requirement.h" #include "reqmaker.h" #include "csutilities.h" +#include +#include #include #include #include // OID coding +#include using namespace CodeSigning; typedef Requirement::Maker Maker; +extern "C" { + +/* Decode a choice of UTCTime or GeneralizedTime to a CFAbsoluteTime. Return +an absoluteTime if the date was valid and properly decoded. Return +NULL_TIME otherwise. */ +CFAbsoluteTime SecAbsoluteTimeFromDateContent(DERTag tag, const uint8_t *bytes, + size_t length); + +} + + ANTLR_BEGIN_NAMESPACE(Security_CodeSigning) // @@ -66,7 +80,12 @@ ANTLR_BEGIN_NAMESPACE(Security_CodeSigning) void RequirementParser::certMatchOperation(Maker &maker, int32_t slot, string key) { - if (matchPrefix(key, "subject.")) { + if (const char *oids = matchPrefix(key, "timestamp.")) { + maker.put(opCertFieldDate); + maker.put(slot); + CssmAutoData oid(Allocator::standard()); oid.fromOid(oids); + maker.putData(oid.data(), oid.length()); + } else if (matchPrefix(key, "subject.")) { maker.put(opCertField); maker.put(slot); maker.put(key); @@ -129,6 +148,8 @@ BlobCore * RequirementParser::autosense() { case LITERAL_identifier: case LITERAL_cdhash: case LITERAL_platform: + case LITERAL_notarized: + case LITERAL_legacy: case LITERAL_anchor: case LITERAL_certificate: case LITERAL_cert: @@ -476,6 +497,18 @@ void RequirementParser::primary( maker.platform(ident); break; } + case LITERAL_notarized: + { + match(LITERAL_notarized); + maker.put(opNotarized); + break; + } + case LITERAL_legacy: + { + match(LITERAL_legacy); + maker.put(opLegacyDevID); + break; + } default: if ((LA(1) == LPAREN) && (_tokenSet_8.member(LA(2)))) { match(LPAREN); @@ -964,78 +997,10 @@ void RequirementParser::match_suffix( maker.put(matchExists); break; } - case EQL: - case EQQL: + case LITERAL_absent: { - { - switch ( LA(1)) { - case EQL: - { - match(EQL); - break; - } - case EQQL: - { - match(EQQL); - break; - } - default: - { - throw antlr::NoViableAltException(LT(1), getFilename()); - } - } - } - MatchOperation mop = matchEqual; string value; - { - switch ( LA(1)) { - case STAR: - { - match(STAR); - mop = matchEndsWith; - break; - } - case HEXCONSTANT: - case DOTKEY: - case STRING: - { - break; - } - default: - { - throw antlr::NoViableAltException(LT(1), getFilename()); - } - } - } - value=datavalue(); - { - switch ( LA(1)) { - case STAR: - { - match(STAR); - mop = (mop == matchEndsWith) ? matchContains : matchBeginsWith; - break; - } - case antlr::Token::EOF_TYPE: - case LITERAL_guest: - case LITERAL_host: - case LITERAL_designated: - case LITERAL_library: - case LITERAL_plugin: - case LITERAL_or: - case LITERAL_and: - case RPAREN: - case INTEGER: - case SEMI: - { - break; - } - default: - { - throw antlr::NoViableAltException(LT(1), getFilename()); - } - } - } - maker.put(mop); maker.put(value); + match(LITERAL_absent); + maker.put(matchAbsent); break; } case SUBS: @@ -1046,40 +1011,150 @@ void RequirementParser::match_suffix( maker.put(matchContains); maker.put(value); break; } - case LESS: - { - match(LESS); - string value; - value=datavalue(); - maker.put(matchLessThan); maker.put(value); - break; - } - case GT: - { - match(GT); - string value; - value=datavalue(); - maker.put(matchGreaterThan); maker.put(value); - break; - } - case LE: - { - match(LE); - string value; - value=datavalue(); - maker.put(matchLessEqual); maker.put(value); - break; - } - case GE: - { - match(GE); - string value; - value=datavalue(); - maker.put(matchGreaterEqual); maker.put(value); - break; - } default: - { + if ((LA(1) == EQL || LA(1) == EQQL) && (_tokenSet_16.member(LA(2)))) { + { + switch ( LA(1)) { + case EQL: + { + match(EQL); + break; + } + case EQQL: + { + match(EQQL); + break; + } + default: + { + throw antlr::NoViableAltException(LT(1), getFilename()); + } + } + } + MatchOperation mop = matchEqual; string value; + { + switch ( LA(1)) { + case STAR: + { + match(STAR); + mop = matchEndsWith; + break; + } + case HEXCONSTANT: + case DOTKEY: + case STRING: + { + break; + } + default: + { + throw antlr::NoViableAltException(LT(1), getFilename()); + } + } + } + value=datavalue(); + { + switch ( LA(1)) { + case STAR: + { + match(STAR); + mop = (mop == matchEndsWith) ? matchContains : matchBeginsWith; + break; + } + case antlr::Token::EOF_TYPE: + case LITERAL_guest: + case LITERAL_host: + case LITERAL_designated: + case LITERAL_library: + case LITERAL_plugin: + case LITERAL_or: + case LITERAL_and: + case RPAREN: + case INTEGER: + case SEMI: + { + break; + } + default: + { + throw antlr::NoViableAltException(LT(1), getFilename()); + } + } + } + maker.put(mop); maker.put(value); + } + else if ((LA(1) == EQL || LA(1) == EQQL) && (LA(2) == LITERAL_timestamp)) { + { + switch ( LA(1)) { + case EQL: + { + match(EQL); + break; + } + case EQQL: + { + match(EQQL); + break; + } + default: + { + throw antlr::NoViableAltException(LT(1), getFilename()); + } + } + } + MatchOperation mop = matchOn; int64_t value; + value=timestamp(); + maker.put(mop); maker.put(value); + } + else if ((LA(1) == LESS) && ((LA(2) >= HEXCONSTANT && LA(2) <= STRING))) { + match(LESS); + string value; + value=datavalue(); + maker.put(matchLessThan); maker.put(value); + } + else if ((LA(1) == GT) && ((LA(2) >= HEXCONSTANT && LA(2) <= STRING))) { + match(GT); + string value; + value=datavalue(); + maker.put(matchGreaterThan); maker.put(value); + } + else if ((LA(1) == LE) && ((LA(2) >= HEXCONSTANT && LA(2) <= STRING))) { + match(LE); + string value; + value=datavalue(); + maker.put(matchLessEqual); maker.put(value); + } + else if ((LA(1) == GE) && ((LA(2) >= HEXCONSTANT && LA(2) <= STRING))) { + match(GE); + string value; + value=datavalue(); + maker.put(matchGreaterEqual); maker.put(value); + } + else if ((LA(1) == LESS) && (LA(2) == LITERAL_timestamp)) { + match(LESS); + int64_t value; + value=timestamp(); + maker.put(matchBefore); maker.put(value); + } + else if ((LA(1) == GT) && (LA(2) == LITERAL_timestamp)) { + match(GT); + int64_t value; + value=timestamp(); + maker.put(matchAfter); maker.put(value); + } + else if ((LA(1) == LE) && (LA(2) == LITERAL_timestamp)) { + match(LE); + int64_t value; + value=timestamp(); + maker.put(matchOnOrBefore); maker.put(value); + } + else if ((LA(1) == GE) && (LA(2) == LITERAL_timestamp)) { + match(GE); + int64_t value; + value=timestamp(); + maker.put(matchOnOrAfter); maker.put(value); + } + else { throw antlr::NoViableAltException(LT(1), getFilename()); } } @@ -1117,7 +1192,24 @@ string RequirementParser::datavalue() { } catch (antlr::RecognitionException& ex) { reportError(ex); - recover(ex,_tokenSet_16); + recover(ex,_tokenSet_17); + } + return result; +} + +int64_t RequirementParser::timestamp() { + int64_t result; + antlr::RefToken s = antlr::nullToken; + + try { // for error handling + match(LITERAL_timestamp); + s = LT(1); + match(STRING); + result = (int64_t)SecAbsoluteTimeFromDateContent(ASN1_GENERALIZED_TIME, (uint8_t const *)s->getText().c_str(), s->getText().length()); + } + catch (antlr::RecognitionException& ex) { + reportError(ex); + recover(ex,_tokenSet_9); } return result; } @@ -1151,7 +1243,7 @@ string RequirementParser::stringvalue() { } catch (antlr::RecognitionException& ex) { reportError(ex); - recover(ex,_tokenSet_17); + recover(ex,_tokenSet_18); } return result; } @@ -1224,6 +1316,8 @@ const char* RequirementParser::tokenNames[] = { "\"identifier\"", "\"cdhash\"", "\"platform\"", + "\"notarized\"", + "\"legacy\"", "\"anchor\"", "\"apple\"", "\"generic\"", @@ -1233,6 +1327,7 @@ const char* RequirementParser::tokenNames[] = { "\"info\"", "\"entitlement\"", "\"exists\"", + "\"absent\"", "EQL", "EQQL", "STAR", @@ -1252,6 +1347,7 @@ const char* RequirementParser::tokenNames[] = { "STRING", "PATHNAME", "INTEGER", + "\"timestamp\"", "SEMI", "IDENT", "HEX", @@ -1266,66 +1362,69 @@ const char* RequirementParser::tokenNames[] = { const unsigned long RequirementParser::_tokenSet_0_data_[] = { 2UL, 0UL, 0UL, 0UL }; // EOF const antlr::BitSet RequirementParser::_tokenSet_0(_tokenSet_0_data_,4); -const unsigned long RequirementParser::_tokenSet_1_data_[] = { 992UL, 131072UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_1_data_[] = { 992UL, 1048576UL, 0UL, 0UL }; // "guest" "host" "designated" "library" "plugin" INTEGER const antlr::BitSet RequirementParser::_tokenSet_1(_tokenSet_1_data_,4); const unsigned long RequirementParser::_tokenSet_2_data_[] = { 16UL, 0UL, 0UL, 0UL }; // ARROW const antlr::BitSet RequirementParser::_tokenSet_2(_tokenSet_2_data_,4); -const unsigned long RequirementParser::_tokenSet_3_data_[] = { 994UL, 131072UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_3_data_[] = { 994UL, 1048576UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" INTEGER const antlr::BitSet RequirementParser::_tokenSet_3(_tokenSet_3_data_,4); -const unsigned long RequirementParser::_tokenSet_4_data_[] = { 2281713650UL, 512129UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_4_data_[] = { 536883186UL, 6194188UL, 0UL, 0UL }; // EOF ARROW "guest" "host" "designated" "library" "plugin" "or" "and" // RPAREN "trusted" EQL EQQL LBRACK HASHCONSTANT DOTKEY STRING PATHNAME // INTEGER SEMI const antlr::BitSet RequirementParser::_tokenSet_4(_tokenSet_4_data_,4); -const unsigned long RequirementParser::_tokenSet_5_data_[] = { 9186UL, 393216UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_5_data_[] = { 9186UL, 5242880UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" RPAREN INTEGER SEMI const antlr::BitSet RequirementParser::_tokenSet_5(_tokenSet_5_data_,4); -const unsigned long RequirementParser::_tokenSet_6_data_[] = { 994UL, 393216UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_6_data_[] = { 994UL, 5242880UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" INTEGER SEMI const antlr::BitSet RequirementParser::_tokenSet_6(_tokenSet_6_data_,4); -const unsigned long RequirementParser::_tokenSet_7_data_[] = { 10210UL, 393216UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_7_data_[] = { 10210UL, 5242880UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" "or" RPAREN INTEGER // SEMI const antlr::BitSet RequirementParser::_tokenSet_7(_tokenSet_7_data_,4); -const unsigned long RequirementParser::_tokenSet_8_data_[] = { 914345984UL, 0UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_8_data_[] = { 3657420800UL, 0UL, 0UL, 0UL }; // LPAREN NOT "always" "true" "never" "false" "identifier" "cdhash" "platform" -// "anchor" "certificate" "cert" "info" "entitlement" +// "notarized" "legacy" "anchor" "certificate" "cert" "info" "entitlement" const antlr::BitSet RequirementParser::_tokenSet_8(_tokenSet_8_data_,4); -const unsigned long RequirementParser::_tokenSet_9_data_[] = { 12258UL, 393216UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_9_data_[] = { 12258UL, 5242880UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN // INTEGER SEMI const antlr::BitSet RequirementParser::_tokenSet_9(_tokenSet_9_data_,4); -const unsigned long RequirementParser::_tokenSet_10_data_[] = { 0UL, 134656UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_10_data_[] = { 0UL, 1077248UL, 0UL, 0UL }; // NEG "leaf" "root" INTEGER const antlr::BitSet RequirementParser::_tokenSet_10(_tokenSet_10_data_,4); -const unsigned long RequirementParser::_tokenSet_11_data_[] = { 2147483648UL, 118913UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_11_data_[] = { 0UL, 951308UL, 0UL, 0UL }; // EQL EQQL LBRACK HASHCONSTANT DOTKEY STRING PATHNAME const antlr::BitSet RequirementParser::_tokenSet_11(_tokenSet_11_data_,4); -const unsigned long RequirementParser::_tokenSet_12_data_[] = { 0UL, 249856UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_12_data_[] = { 0UL, 1998848UL, 0UL, 0UL }; // HASHCONSTANT DOTKEY STRING PATHNAME INTEGER const antlr::BitSet RequirementParser::_tokenSet_12(_tokenSet_12_data_,4); -const unsigned long RequirementParser::_tokenSet_13_data_[] = { 2281701376UL, 118913UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_13_data_[] = { 536870912UL, 951308UL, 0UL, 0UL }; // "trusted" EQL EQQL LBRACK HASHCONSTANT DOTKEY STRING PATHNAME const antlr::BitSet RequirementParser::_tokenSet_13(_tokenSet_13_data_,4); -const unsigned long RequirementParser::_tokenSet_14_data_[] = { 1073754082UL, 512000UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_14_data_[] = { 12258UL, 6193153UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN // "exists" HASHCONSTANT DOTKEY STRING PATHNAME INTEGER SEMI const antlr::BitSet RequirementParser::_tokenSet_14(_tokenSet_14_data_,4); -const unsigned long RequirementParser::_tokenSet_15_data_[] = { 3221237730UL, 393341UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_15_data_[] = { 12258UL, 5243887UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN -// "exists" EQL EQQL SUBS LESS GT LE GE INTEGER SEMI +// "exists" "absent" EQL EQQL SUBS LESS GT LE GE INTEGER SEMI const antlr::BitSet RequirementParser::_tokenSet_15(_tokenSet_15_data_,4); -const unsigned long RequirementParser::_tokenSet_16_data_[] = { 12258UL, 393218UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_16_data_[] = { 0UL, 458768UL, 0UL, 0UL }; +// STAR HEXCONSTANT DOTKEY STRING +const antlr::BitSet RequirementParser::_tokenSet_16(_tokenSet_16_data_,4); +const unsigned long RequirementParser::_tokenSet_17_data_[] = { 12258UL, 5242896UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN // STAR INTEGER SEMI -const antlr::BitSet RequirementParser::_tokenSet_16(_tokenSet_16_data_,4); -const unsigned long RequirementParser::_tokenSet_17_data_[] = { 12258UL, 393474UL, 0UL, 0UL }; +const antlr::BitSet RequirementParser::_tokenSet_17(_tokenSet_17_data_,4); +const unsigned long RequirementParser::_tokenSet_18_data_[] = { 12258UL, 5244944UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN // STAR RBRACK INTEGER SEMI -const antlr::BitSet RequirementParser::_tokenSet_17(_tokenSet_17_data_,4); +const antlr::BitSet RequirementParser::_tokenSet_18(_tokenSet_18_data_,4); ANTLR_END_NAMESPACE