1 /* $ANTLR 2.7.7 (20121221): "requirements.grammar" -> "RequirementParser.cpp"$ */
2 #include "RequirementParser.hpp"
3 #include <antlr/NoViableAltException.hpp>
4 #include <antlr/SemanticException.hpp>
5 #include <antlr/ASTFactory.hpp>
7 #include "requirement.h"
9 #include "csutilities.h"
10 #include <security_utilities/cfutilities.h>
11 #include <security_utilities/hashing.h>
12 #include <security_cdsa_utilities/cssmdata.h> // OID coding
13 using namespace CodeSigning
;
14 typedef Requirement::Maker Maker
;
16 ANTLR_BEGIN_NAMESPACE(Security_CodeSigning
)
19 // Collect error messages.
20 // Note that the immediate caller takes the absence of collected error messages
21 // to indicate compilation success.
23 void RequirementParser::reportError(const antlr::RecognitionException
&ex
)
25 errors
+= ex
.toString() + "\n";
28 void RequirementParser::reportError(const std::string
&s
)
35 // Parser helper functions
37 string
RequirementParser::hexString(const string
&s
)
40 throw antlr::SemanticException("odd number of digits");
41 const char *p
= s
.data();
43 for (unsigned n
= 0; n
< s
.length(); n
+= 2) {
45 sscanf(p
+n
, "%2hhx", &c
);
51 void RequirementParser::hashString(const string
&s
, SHA1::Digest hash
)
53 if (s
.size() != 2 * SHA1::digestLength
)
54 throw antlr::SemanticException("invalid hash length");
55 memcpy(hash
, hexString(s
).data(), SHA1::digestLength
);
58 static const char *matchPrefix(const string
&key
, const char *prefix
)
60 size_t pLength
= strlen(prefix
);
61 if (!key
.compare(0, pLength
, prefix
, 0, pLength
))
62 return key
.c_str() + pLength
;
67 void RequirementParser::certMatchOperation(Maker
&maker
, int32_t slot
, string key
)
69 if (matchPrefix(key
, "subject.")) {
70 maker
.put(opCertField
);
73 } else if (const char *oids
= matchPrefix(key
, "field.")) {
74 maker
.put(opCertGeneric
);
76 CssmAutoData
oid(Allocator::standard()); oid
.fromOid(oids
);
77 maker
.putData(oid
.data(), oid
.length());
78 } else if (const char *oids
= matchPrefix(key
, "extension.")) {
79 maker
.put(opCertGeneric
);
81 CssmAutoData
oid(Allocator::standard()); oid
.fromOid(oids
);
82 maker
.putData(oid
.data(), oid
.length());
83 } else if (const char *oids
= matchPrefix(key
, "policy.")) {
84 maker
.put(opCertPolicy
);
86 CssmAutoData
oid(Allocator::standard()); oid
.fromOid(oids
);
87 maker
.putData(oid
.data(), oid
.length());
89 throw antlr::SemanticException(key
+ ": unrecognized certificate field");
93 RequirementParser::RequirementParser(antlr::TokenBuffer
& tokenBuf
, int k
)
94 : antlr::LLkParser(tokenBuf
,k
)
98 RequirementParser::RequirementParser(antlr::TokenBuffer
& tokenBuf
)
99 : antlr::LLkParser(tokenBuf
,2)
103 RequirementParser::RequirementParser(antlr::TokenStream
& lexer
, int k
)
104 : antlr::LLkParser(lexer
,k
)
108 RequirementParser::RequirementParser(antlr::TokenStream
& lexer
)
109 : antlr::LLkParser(lexer
,2)
113 RequirementParser::RequirementParser(const antlr::ParserSharedInputState
& state
)
114 : antlr::LLkParser(state
,2)
118 BlobCore
* RequirementParser::autosense() {
119 BlobCore
*result
= NULL
;
121 try { // for error handling
129 case LITERAL_identifier
:
131 case LITERAL_platform
:
132 case LITERAL_notarized
:
134 case LITERAL_certificate
:
137 case LITERAL_entitlement
:
139 result
=requirement();
144 case LITERAL_designated
:
145 case LITERAL_library
:
149 result
=requirementSet();
154 throw antlr::NoViableAltException(LT(1), getFilename());
158 catch (antlr::RecognitionException
& ex
) {
160 recover(ex
,_tokenSet_0
);
165 Requirement
* RequirementParser::requirement() {
166 Requirement
*result
= NULL
;
168 try { // for error handling
169 result
=requirementElement();
170 match(antlr::Token::EOF_TYPE
);
172 catch (antlr::RecognitionException
& ex
) {
174 recover(ex
,_tokenSet_0
);
179 Requirements
* RequirementParser::requirementSet() {
180 Requirements
*result
= NULL
;
181 Requirements::Maker maker
;
183 try { // for error handling
187 if ((_tokenSet_1
.member(LA(1)))) {
188 uint32_t t
; Requirement
*req
;
191 req
=requirementElement();
195 if ( _cnt4
>=1 ) { goto _loop4
; } else {throw antlr::NoViableAltException(LT(1), getFilename());}
202 result
= errors
.empty() ? maker() : NULL
;
203 match(antlr::Token::EOF_TYPE
);
205 catch (antlr::RecognitionException
& ex
) {
207 recover(ex
,_tokenSet_0
);
212 uint32_t RequirementParser::requirementType() {
213 uint32_t type
= kSecInvalidRequirementType
;
215 try { // for error handling
219 match(LITERAL_guest
);
220 type
= kSecGuestRequirementType
;
226 type
= kSecHostRequirementType
;
229 case LITERAL_designated
:
231 match(LITERAL_designated
);
232 type
= kSecDesignatedRequirementType
;
235 case LITERAL_library
:
237 match(LITERAL_library
);
238 type
= kSecLibraryRequirementType
;
243 match(LITERAL_plugin
);
244 type
= kSecPluginRequirementType
;
254 throw antlr::NoViableAltException(LT(1), getFilename());
258 catch (antlr::RecognitionException
& ex
) {
260 recover(ex
,_tokenSet_2
);
265 Requirement
* RequirementParser::requirementElement() {
266 Requirement
*result
= NULL
;
267 Requirement::Maker maker
;
269 try { // for error handling
274 if ((LA(1) == SEMI
)) {
285 catch (antlr::RecognitionException
& ex
) {
287 recover(ex
,_tokenSet_3
);
292 int32_t RequirementParser::integer() {
294 antlr::RefToken s
= antlr::nullToken
;
296 try { // for error handling
299 result
= int32_t(atol(s
->getText().c_str()));
301 catch (antlr::RecognitionException
& ex
) {
303 recover(ex
,_tokenSet_4
);
308 void RequirementParser::expr(
311 Maker::Label
label(maker
);
313 try { // for error handling
317 if ((LA(1) == LITERAL_or
)) {
319 maker
.insert
<ExprOp
>(label
) = opOr
;
330 catch (antlr::RecognitionException
& ex
) {
332 recover(ex
,_tokenSet_5
);
336 void RequirementParser::fluff() {
338 try { // for error handling
341 catch (antlr::RecognitionException
& ex
) {
343 recover(ex
,_tokenSet_6
);
347 void RequirementParser::term(
350 Maker::Label
label(maker
);
352 try { // for error handling
356 if ((LA(1) == LITERAL_and
)) {
358 maker
.insert
<ExprOp
>(label
) = opAnd
;
369 catch (antlr::RecognitionException
& ex
) {
371 recover(ex
,_tokenSet_7
);
375 void RequirementParser::primary(
379 try { // for error handling
395 match(LITERAL_always
);
405 throw antlr::NoViableAltException(LT(1), getFilename());
419 match(LITERAL_never
);
424 match(LITERAL_false
);
429 throw antlr::NoViableAltException(LT(1), getFilename());
437 case LITERAL_certificate
:
448 case LITERAL_entitlement
:
450 entitlementspec(maker
);
453 case LITERAL_identifier
:
455 match(LITERAL_identifier
);
458 code
=identifierString();
464 match(LITERAL_cdhash
);
468 maker
.cdhash(digest
);
471 case LITERAL_platform
:
473 match(LITERAL_platform
);
477 maker
.platform(ident
);
480 case LITERAL_notarized
:
482 match(LITERAL_notarized
);
483 maker
.put(opNotarized
);
487 if ((LA(1) == LPAREN
) && (_tokenSet_8
.member(LA(2)))) {
492 else if ((LA(1) == LPAREN
) && (LA(2) == DOTKEY
|| LA(2) == STRING
)) {
495 name
=identifierString();
497 maker
.put(opNamedCode
); maker
.put(name
);
500 throw antlr::NoViableAltException(LT(1), getFilename());
504 catch (antlr::RecognitionException
& ex
) {
506 recover(ex
,_tokenSet_9
);
510 void RequirementParser::certspec(
514 try { // for error handling
515 if ((LA(1) == LITERAL_anchor
) && (LA(2) == LITERAL_apple
)) {
516 match(LITERAL_anchor
);
517 match(LITERAL_apple
);
520 else if ((LA(1) == LITERAL_anchor
) && (LA(2) == LITERAL_generic
)) {
521 match(LITERAL_anchor
);
522 match(LITERAL_generic
);
523 match(LITERAL_apple
);
524 maker
.put(opAppleGenericAnchor
);
526 else if ((LA(1) == LITERAL_anchor
|| LA(1) == LITERAL_certificate
|| LA(1) == LITERAL_cert
) && (LA(2) == LITERAL_trusted
)) {
529 case LITERAL_certificate
:
531 match(LITERAL_certificate
);
541 match(LITERAL_anchor
);
546 throw antlr::NoViableAltException(LT(1), getFilename());
550 match(LITERAL_trusted
);
551 maker
.trustedAnchor();
553 else if ((LA(1) == LITERAL_certificate
|| LA(1) == LITERAL_cert
) && (_tokenSet_10
.member(LA(2)))) {
556 case LITERAL_certificate
:
558 match(LITERAL_certificate
);
568 throw antlr::NoViableAltException(LT(1), getFilename());
584 certslotspec(maker
, slot
);
587 case LITERAL_trusted
:
589 match(LITERAL_trusted
);
590 maker
.trustedAnchor(slot
);
595 throw antlr::NoViableAltException(LT(1), getFilename());
600 else if ((LA(1) == LITERAL_anchor
) && (_tokenSet_11
.member(LA(2)))) {
601 match(LITERAL_anchor
);
602 certslotspec(maker
, Requirement::anchorCert
);
605 throw antlr::NoViableAltException(LT(1), getFilename());
609 catch (antlr::RecognitionException
& ex
) {
611 recover(ex
,_tokenSet_9
);
615 void RequirementParser::infospec(
620 try { // for error handling
623 maker
.put(opInfoKeyField
); maker
.put(key
);
626 catch (antlr::RecognitionException
& ex
) {
628 recover(ex
,_tokenSet_9
);
632 void RequirementParser::entitlementspec(
637 try { // for error handling
638 match(LITERAL_entitlement
);
640 maker
.put(opEntitlementField
); maker
.put(key
);
643 catch (antlr::RecognitionException
& ex
) {
645 recover(ex
,_tokenSet_9
);
649 void RequirementParser::eql() {
651 try { // for error handling
674 throw antlr::NoViableAltException(LT(1), getFilename());
678 catch (antlr::RecognitionException
& ex
) {
680 recover(ex
,_tokenSet_12
);
684 string
RequirementParser::identifierString() {
686 antlr::RefToken dk
= antlr::nullToken
;
687 antlr::RefToken s
= antlr::nullToken
;
689 try { // for error handling
695 result
= dk
->getText();
702 result
= s
->getText();
707 throw antlr::NoViableAltException(LT(1), getFilename());
711 catch (antlr::RecognitionException
& ex
) {
713 recover(ex
,_tokenSet_9
);
718 void RequirementParser::hash(
721 antlr::RefToken hash
= antlr::nullToken
;
723 try { // for error handling
726 hashString(hash
->getText(), digest
);
728 catch (antlr::RecognitionException
& ex
) {
730 recover(ex
,_tokenSet_9
);
734 void RequirementParser::appleanchor(
738 try { // for error handling
740 case antlr::Token::EOF_TYPE
:
743 case LITERAL_designated
:
744 case LITERAL_library
:
753 maker
.put(opAppleAnchor
);
756 case LITERAL_generic
:
758 match(LITERAL_generic
);
759 maker
.put(opAppleGenericAnchor
);
766 name
=identifierString();
767 maker
.put(opNamedAnchor
); maker
.put(name
);
772 throw antlr::NoViableAltException(LT(1), getFilename());
776 catch (antlr::RecognitionException
& ex
) {
778 recover(ex
,_tokenSet_9
);
782 int32_t RequirementParser::certSlot() {
785 try { // for error handling
802 slot
= Requirement::leafCert
;
808 slot
= Requirement::anchorCert
;
813 throw antlr::NoViableAltException(LT(1), getFilename());
817 catch (antlr::RecognitionException
& ex
) {
819 recover(ex
,_tokenSet_13
);
824 void RequirementParser::certslotspec(
825 Maker
&maker
, int32_t slot
829 try { // for error handling
840 certificateDigest(digest
);
841 maker
.anchor(slot
, digest
);
847 certMatchOperation(maker
, slot
, key
);
853 throw antlr::NoViableAltException(LT(1), getFilename());
857 catch (antlr::RecognitionException
& ex
) {
859 recover(ex
,_tokenSet_9
);
863 void RequirementParser::empty() {
865 try { // for error handling
867 catch (antlr::RecognitionException
& ex
) {
869 recover(ex
,_tokenSet_14
);
873 void RequirementParser::certificateDigest(
877 try { // for error handling
890 if (CFRef
<CFDataRef
> certData
= cfLoadFile(path
))
891 hashOfCertificate(CFDataGetBytePtr(certData
), CFDataGetLength(certData
), digest
);
893 throw antlr::SemanticException(path
+ ": not found");
899 throw antlr::NoViableAltException(LT(1), getFilename());
903 catch (antlr::RecognitionException
& ex
) {
905 recover(ex
,_tokenSet_9
);
909 string
RequirementParser::bracketKey() {
912 try { // for error handling
917 catch (antlr::RecognitionException
& ex
) {
919 recover(ex
,_tokenSet_15
);
924 void RequirementParser::match_suffix(
928 try { // for error handling
930 case antlr::Token::EOF_TYPE
:
933 case LITERAL_designated
:
934 case LITERAL_library
:
948 match(LITERAL_exists
);
951 case antlr::Token::EOF_TYPE
:
954 case LITERAL_designated
:
955 case LITERAL_library
:
967 throw antlr::NoViableAltException(LT(1), getFilename());
971 maker
.put(matchExists
);
991 throw antlr::NoViableAltException(LT(1), getFilename());
995 MatchOperation mop
= matchEqual
; string value
;
1001 mop
= matchEndsWith
;
1012 throw antlr::NoViableAltException(LT(1), getFilename());
1022 mop
= (mop
== matchEndsWith
) ? matchContains
: matchBeginsWith
;
1025 case antlr::Token::EOF_TYPE
:
1028 case LITERAL_designated
:
1029 case LITERAL_library
:
1030 case LITERAL_plugin
:
1041 throw antlr::NoViableAltException(LT(1), getFilename());
1045 maker
.put(mop
); maker
.put(value
);
1053 maker
.put(matchContains
); maker
.put(value
);
1061 maker
.put(matchLessThan
); maker
.put(value
);
1069 maker
.put(matchGreaterThan
); maker
.put(value
);
1077 maker
.put(matchLessEqual
); maker
.put(value
);
1085 maker
.put(matchGreaterEqual
); maker
.put(value
);
1090 throw antlr::NoViableAltException(LT(1), getFilename());
1094 catch (antlr::RecognitionException
& ex
) {
1096 recover(ex
,_tokenSet_9
);
1100 string
RequirementParser::datavalue() {
1102 antlr::RefToken hex
= antlr::nullToken
;
1104 try { // for error handling
1109 result
=stringvalue();
1116 result
= hexString(hex
->getText());
1121 throw antlr::NoViableAltException(LT(1), getFilename());
1125 catch (antlr::RecognitionException
& ex
) {
1127 recover(ex
,_tokenSet_16
);
1132 string
RequirementParser::stringvalue() {
1134 antlr::RefToken dk
= antlr::nullToken
;
1135 antlr::RefToken s
= antlr::nullToken
;
1137 try { // for error handling
1143 result
= dk
->getText();
1150 result
= s
->getText();
1155 throw antlr::NoViableAltException(LT(1), getFilename());
1159 catch (antlr::RecognitionException
& ex
) {
1161 recover(ex
,_tokenSet_17
);
1166 string
RequirementParser::pathstring() {
1168 antlr::RefToken dk
= antlr::nullToken
;
1169 antlr::RefToken s
= antlr::nullToken
;
1170 antlr::RefToken pn
= antlr::nullToken
;
1172 try { // for error handling
1178 result
= dk
->getText();
1185 result
= s
->getText();
1192 result
= pn
->getText();
1197 throw antlr::NoViableAltException(LT(1), getFilename());
1201 catch (antlr::RecognitionException
& ex
) {
1203 recover(ex
,_tokenSet_9
);
1208 void RequirementParser::initializeASTFactory( antlr::ASTFactory
& )
1211 const char* RequirementParser::tokenNames
[] = {
1215 "NULL_TREE_LOOKAHEAD",
1274 const unsigned long RequirementParser::_tokenSet_0_data_
[] = { 2UL, 0UL, 0UL, 0UL };
1276 const antlr::BitSet
RequirementParser::_tokenSet_0(_tokenSet_0_data_
,4);
1277 const unsigned long RequirementParser::_tokenSet_1_data_
[] = { 992UL, 262144UL, 0UL, 0UL };
1278 // "guest" "host" "designated" "library" "plugin" INTEGER
1279 const antlr::BitSet
RequirementParser::_tokenSet_1(_tokenSet_1_data_
,4);
1280 const unsigned long RequirementParser::_tokenSet_2_data_
[] = { 16UL, 0UL, 0UL, 0UL };
1282 const antlr::BitSet
RequirementParser::_tokenSet_2(_tokenSet_2_data_
,4);
1283 const unsigned long RequirementParser::_tokenSet_3_data_
[] = { 994UL, 262144UL, 0UL, 0UL };
1284 // EOF "guest" "host" "designated" "library" "plugin" INTEGER
1285 const antlr::BitSet
RequirementParser::_tokenSet_3(_tokenSet_3_data_
,4);
1286 const unsigned long RequirementParser::_tokenSet_4_data_
[] = { 268447730UL, 1024259UL, 0UL, 0UL };
1287 // EOF ARROW "guest" "host" "designated" "library" "plugin" "or" "and"
1288 // RPAREN "trusted" EQL EQQL LBRACK HASHCONSTANT DOTKEY STRING PATHNAME
1290 const antlr::BitSet
RequirementParser::_tokenSet_4(_tokenSet_4_data_
,4);
1291 const unsigned long RequirementParser::_tokenSet_5_data_
[] = { 9186UL, 786432UL, 0UL, 0UL };
1292 // EOF "guest" "host" "designated" "library" "plugin" RPAREN INTEGER SEMI
1293 const antlr::BitSet
RequirementParser::_tokenSet_5(_tokenSet_5_data_
,4);
1294 const unsigned long RequirementParser::_tokenSet_6_data_
[] = { 994UL, 786432UL, 0UL, 0UL };
1295 // EOF "guest" "host" "designated" "library" "plugin" INTEGER SEMI
1296 const antlr::BitSet
RequirementParser::_tokenSet_6(_tokenSet_6_data_
,4);
1297 const unsigned long RequirementParser::_tokenSet_7_data_
[] = { 10210UL, 786432UL, 0UL, 0UL };
1298 // EOF "guest" "host" "designated" "library" "plugin" "or" RPAREN INTEGER
1300 const antlr::BitSet
RequirementParser::_tokenSet_7(_tokenSet_7_data_
,4);
1301 const unsigned long RequirementParser::_tokenSet_8_data_
[] = { 1828704256UL, 0UL, 0UL, 0UL };
1302 // LPAREN NOT "always" "true" "never" "false" "identifier" "cdhash" "platform"
1303 // "notarized" "anchor" "certificate" "cert" "info" "entitlement"
1304 const antlr::BitSet
RequirementParser::_tokenSet_8(_tokenSet_8_data_
,4);
1305 const unsigned long RequirementParser::_tokenSet_9_data_
[] = { 12258UL, 786432UL, 0UL, 0UL };
1306 // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN
1308 const antlr::BitSet
RequirementParser::_tokenSet_9(_tokenSet_9_data_
,4);
1309 const unsigned long RequirementParser::_tokenSet_10_data_
[] = { 0UL, 269312UL, 0UL, 0UL };
1310 // NEG "leaf" "root" INTEGER
1311 const antlr::BitSet
RequirementParser::_tokenSet_10(_tokenSet_10_data_
,4);
1312 const unsigned long RequirementParser::_tokenSet_11_data_
[] = { 0UL, 237827UL, 0UL, 0UL };
1313 // EQL EQQL LBRACK HASHCONSTANT DOTKEY STRING PATHNAME
1314 const antlr::BitSet
RequirementParser::_tokenSet_11(_tokenSet_11_data_
,4);
1315 const unsigned long RequirementParser::_tokenSet_12_data_
[] = { 0UL, 499712UL, 0UL, 0UL };
1316 // HASHCONSTANT DOTKEY STRING PATHNAME INTEGER
1317 const antlr::BitSet
RequirementParser::_tokenSet_12(_tokenSet_12_data_
,4);
1318 const unsigned long RequirementParser::_tokenSet_13_data_
[] = { 268435456UL, 237827UL, 0UL, 0UL };
1319 // "trusted" EQL EQQL LBRACK HASHCONSTANT DOTKEY STRING PATHNAME
1320 const antlr::BitSet
RequirementParser::_tokenSet_13(_tokenSet_13_data_
,4);
1321 const unsigned long RequirementParser::_tokenSet_14_data_
[] = { 2147495906UL, 1024000UL, 0UL, 0UL };
1322 // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN
1323 // "exists" HASHCONSTANT DOTKEY STRING PATHNAME INTEGER SEMI
1324 const antlr::BitSet
RequirementParser::_tokenSet_14(_tokenSet_14_data_
,4);
1325 const unsigned long RequirementParser::_tokenSet_15_data_
[] = { 2147495906UL, 786683UL, 0UL, 0UL };
1326 // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN
1327 // "exists" EQL EQQL SUBS LESS GT LE GE INTEGER SEMI
1328 const antlr::BitSet
RequirementParser::_tokenSet_15(_tokenSet_15_data_
,4);
1329 const unsigned long RequirementParser::_tokenSet_16_data_
[] = { 12258UL, 786436UL, 0UL, 0UL };
1330 // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN
1331 // STAR INTEGER SEMI
1332 const antlr::BitSet
RequirementParser::_tokenSet_16(_tokenSet_16_data_
,4);
1333 const unsigned long RequirementParser::_tokenSet_17_data_
[] = { 12258UL, 786948UL, 0UL, 0UL };
1334 // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN
1335 // STAR RBRACK INTEGER SEMI
1336 const antlr::BitSet
RequirementParser::_tokenSet_17(_tokenSet_17_data_
,4);