]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_codesigning/requirements.grammar
Security-58286.260.20.tar.gz
[apple/security.git] / OSX / libsecurity_codesigning / requirements.grammar
index 2886f22ca964b055cbc18bb338514887bc6c94c8..953dd0a3024f16888170942ad9e0e8a0abb43c3d 100644 (file)
@@ -47,11 +47,25 @@ header "post_include_cpp" {
 #include "requirement.h"
 #include "reqmaker.h"
 #include "csutilities.h"
+#include <libDER/libDER.h>
+#include <libDER/asn1Types.h>
 #include <security_utilities/cfutilities.h>
 #include <security_utilities/hashing.h>
 #include <security_cdsa_utilities/cssmdata.h>  // OID coding
+#include <Security/SecCertificate.h>
 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';
 }