X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/dbe775057b53a81d9983d810772462c3233fccd3..07691282a056c4efea71e1e505527601e8cc166b:/OSX/libsecurity_codesigning/requirements.grammar diff --git a/OSX/libsecurity_codesigning/requirements.grammar b/OSX/libsecurity_codesigning/requirements.grammar index 2886f22c..953dd0a3 100644 --- a/OSX/libsecurity_codesigning/requirements.grammar +++ b/OSX/libsecurity_codesigning/requirements.grammar @@ -47,11 +47,25 @@ header "post_include_cpp" { #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); + +} + } options { @@ -115,7 +129,12 @@ options { 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); @@ -308,12 +327,18 @@ entitlementspec[Maker &maker] { string key; } match_suffix[Maker &maker] : empty ( "exists" ) ? { maker.put(matchExists); } + | "absent" + { maker.put(matchAbsent); } | ( EQL | EQQL ) { MatchOperation mop = matchEqual; string value; } ( STAR { mop = matchEndsWith; } ) ? value=datavalue ( STAR { mop = (mop == matchEndsWith) ? matchContains : matchBeginsWith; } ) ? { maker.put(mop); maker.put(value); } + | ( EQL | EQQL ) + { MatchOperation mop = matchOn; int64_t value; } + value=timestamp + { maker.put(mop); maker.put(value); } | SUBS { string value; } value=datavalue { maker.put(matchContains); maker.put(value); } | LESS { string value; } value=datavalue @@ -324,6 +349,14 @@ match_suffix[Maker &maker] { maker.put(matchLessEqual); maker.put(value); } | GE { string value; } value=datavalue { maker.put(matchGreaterEqual); maker.put(value); } + | LESS { int64_t value; } value=timestamp + { maker.put(matchBefore); maker.put(value); } + | GT { int64_t value; } value=timestamp + { maker.put(matchAfter); maker.put(value); } + | LE { int64_t value; } value=timestamp + { maker.put(matchOnOrBefore); maker.put(value); } + | GE { int64_t value; } value=timestamp + { maker.put(matchOnOrAfter); maker.put(value); } ; bracketKey returns [string key] @@ -390,6 +423,11 @@ integer returns [int32_t result] : s:INTEGER { result = int32_t(atol(s->getText().c_str())); } ; +// timestamps +timestamp returns [int64_t result] + : "timestamp" s:STRING { result = (int64_t)SecAbsoluteTimeFromDateContent(ASN1_GENERALIZED_TIME, (uint8_t const *)s->getText().c_str(), s->getText().length()); } + ; + // syntactic cavity generators fluff : SEMI @@ -419,8 +457,7 @@ options { k=2; testLiterals=false; - // Pass through valid UTF-8 (which excludes hex C0-C1 and F5-FF), - // but also exclude ASCII control characters below 0x20 (space). + // Pass through valid UTF-8 (which excludes hex C0-C1 and F5-FF). // Byte ranges according to Unicode 11.0, paragraph 3.9 D92. charVocabulary='\000'..'\277' | '\302'..'\364'; }