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
:
133 case LITERAL_certificate
:
136 case LITERAL_entitlement
:
138 result
=requirement();
143 case LITERAL_designated
:
144 case LITERAL_library
:
148 result
=requirementSet();
153 throw antlr::NoViableAltException(LT(1), getFilename());
157 catch (antlr::RecognitionException
& ex
) {
159 recover(ex
,_tokenSet_0
);
164 Requirement
* RequirementParser::requirement() {
165 Requirement
*result
= NULL
;
167 try { // for error handling
168 result
=requirementElement();
169 match(antlr::Token::EOF_TYPE
);
171 catch (antlr::RecognitionException
& ex
) {
173 recover(ex
,_tokenSet_0
);
178 Requirements
* RequirementParser::requirementSet() {
179 Requirements
*result
= NULL
;
180 Requirements::Maker maker
;
182 try { // for error handling
186 if ((_tokenSet_1
.member(LA(1)))) {
187 uint32_t t
; Requirement
*req
;
190 req
=requirementElement();
194 if ( _cnt4
>=1 ) { goto _loop4
; } else {throw antlr::NoViableAltException(LT(1), getFilename());}
201 result
= errors
.empty() ? maker() : NULL
;
202 match(antlr::Token::EOF_TYPE
);
204 catch (antlr::RecognitionException
& ex
) {
206 recover(ex
,_tokenSet_0
);
211 uint32_t RequirementParser::requirementType() {
212 uint32_t type
= kSecInvalidRequirementType
;
214 try { // for error handling
218 match(LITERAL_guest
);
219 type
= kSecGuestRequirementType
;
225 type
= kSecHostRequirementType
;
228 case LITERAL_designated
:
230 match(LITERAL_designated
);
231 type
= kSecDesignatedRequirementType
;
234 case LITERAL_library
:
236 match(LITERAL_library
);
237 type
= kSecLibraryRequirementType
;
242 match(LITERAL_plugin
);
243 type
= kSecPluginRequirementType
;
253 throw antlr::NoViableAltException(LT(1), getFilename());
257 catch (antlr::RecognitionException
& ex
) {
259 recover(ex
,_tokenSet_2
);
264 Requirement
* RequirementParser::requirementElement() {
265 Requirement
*result
= NULL
;
266 Requirement::Maker maker
;
268 try { // for error handling
273 if ((LA(1) == SEMI
)) {
284 catch (antlr::RecognitionException
& ex
) {
286 recover(ex
,_tokenSet_3
);
291 int32_t RequirementParser::integer() {
293 antlr::RefToken s
= antlr::nullToken
;
295 try { // for error handling
298 result
= int32_t(atol(s
->getText().c_str()));
300 catch (antlr::RecognitionException
& ex
) {
302 recover(ex
,_tokenSet_4
);
307 void RequirementParser::expr(
310 Maker::Label
label(maker
);
312 try { // for error handling
316 if ((LA(1) == LITERAL_or
)) {
318 maker
.insert
<ExprOp
>(label
) = opOr
;
329 catch (antlr::RecognitionException
& ex
) {
331 recover(ex
,_tokenSet_5
);
335 void RequirementParser::fluff() {
337 try { // for error handling
340 catch (antlr::RecognitionException
& ex
) {
342 recover(ex
,_tokenSet_6
);
346 void RequirementParser::term(
349 Maker::Label
label(maker
);
351 try { // for error handling
355 if ((LA(1) == LITERAL_and
)) {
357 maker
.insert
<ExprOp
>(label
) = opAnd
;
368 catch (antlr::RecognitionException
& ex
) {
370 recover(ex
,_tokenSet_7
);
374 void RequirementParser::primary(
378 try { // for error handling
394 match(LITERAL_always
);
404 throw antlr::NoViableAltException(LT(1), getFilename());
418 match(LITERAL_never
);
423 match(LITERAL_false
);
428 throw antlr::NoViableAltException(LT(1), getFilename());
436 case LITERAL_certificate
:
447 case LITERAL_entitlement
:
449 entitlementspec(maker
);
452 case LITERAL_identifier
:
454 match(LITERAL_identifier
);
457 code
=identifierString();
463 match(LITERAL_cdhash
);
467 maker
.cdhash(digest
);
470 case LITERAL_platform
:
472 match(LITERAL_platform
);
476 maker
.platform(ident
);
480 if ((LA(1) == LPAREN
) && (_tokenSet_8
.member(LA(2)))) {
485 else if ((LA(1) == LPAREN
) && (LA(2) == DOTKEY
|| LA(2) == STRING
)) {
488 name
=identifierString();
490 maker
.put(opNamedCode
); maker
.put(name
);
493 throw antlr::NoViableAltException(LT(1), getFilename());
497 catch (antlr::RecognitionException
& ex
) {
499 recover(ex
,_tokenSet_9
);
503 void RequirementParser::certspec(
507 try { // for error handling
508 if ((LA(1) == LITERAL_anchor
) && (LA(2) == LITERAL_apple
)) {
509 match(LITERAL_anchor
);
510 match(LITERAL_apple
);
513 else if ((LA(1) == LITERAL_anchor
) && (LA(2) == LITERAL_generic
)) {
514 match(LITERAL_anchor
);
515 match(LITERAL_generic
);
516 match(LITERAL_apple
);
517 maker
.put(opAppleGenericAnchor
);
519 else if ((LA(1) == LITERAL_anchor
|| LA(1) == LITERAL_certificate
|| LA(1) == LITERAL_cert
) && (LA(2) == LITERAL_trusted
)) {
522 case LITERAL_certificate
:
524 match(LITERAL_certificate
);
534 match(LITERAL_anchor
);
539 throw antlr::NoViableAltException(LT(1), getFilename());
543 match(LITERAL_trusted
);
544 maker
.trustedAnchor();
546 else if ((LA(1) == LITERAL_certificate
|| LA(1) == LITERAL_cert
) && (_tokenSet_10
.member(LA(2)))) {
549 case LITERAL_certificate
:
551 match(LITERAL_certificate
);
561 throw antlr::NoViableAltException(LT(1), getFilename());
577 certslotspec(maker
, slot
);
580 case LITERAL_trusted
:
582 match(LITERAL_trusted
);
583 maker
.trustedAnchor(slot
);
588 throw antlr::NoViableAltException(LT(1), getFilename());
593 else if ((LA(1) == LITERAL_anchor
) && (_tokenSet_11
.member(LA(2)))) {
594 match(LITERAL_anchor
);
595 certslotspec(maker
, Requirement::anchorCert
);
598 throw antlr::NoViableAltException(LT(1), getFilename());
602 catch (antlr::RecognitionException
& ex
) {
604 recover(ex
,_tokenSet_9
);
608 void RequirementParser::infospec(
613 try { // for error handling
616 maker
.put(opInfoKeyField
); maker
.put(key
);
619 catch (antlr::RecognitionException
& ex
) {
621 recover(ex
,_tokenSet_9
);
625 void RequirementParser::entitlementspec(
630 try { // for error handling
631 match(LITERAL_entitlement
);
633 maker
.put(opEntitlementField
); maker
.put(key
);
636 catch (antlr::RecognitionException
& ex
) {
638 recover(ex
,_tokenSet_9
);
642 void RequirementParser::eql() {
644 try { // for error handling
667 throw antlr::NoViableAltException(LT(1), getFilename());
671 catch (antlr::RecognitionException
& ex
) {
673 recover(ex
,_tokenSet_12
);
677 string
RequirementParser::identifierString() {
679 antlr::RefToken dk
= antlr::nullToken
;
680 antlr::RefToken s
= antlr::nullToken
;
682 try { // for error handling
688 result
= dk
->getText();
695 result
= s
->getText();
700 throw antlr::NoViableAltException(LT(1), getFilename());
704 catch (antlr::RecognitionException
& ex
) {
706 recover(ex
,_tokenSet_9
);
711 void RequirementParser::hash(
714 antlr::RefToken hash
= antlr::nullToken
;
716 try { // for error handling
719 hashString(hash
->getText(), digest
);
721 catch (antlr::RecognitionException
& ex
) {
723 recover(ex
,_tokenSet_9
);
727 void RequirementParser::appleanchor(
731 try { // for error handling
733 case antlr::Token::EOF_TYPE
:
736 case LITERAL_designated
:
737 case LITERAL_library
:
746 maker
.put(opAppleAnchor
);
749 case LITERAL_generic
:
751 match(LITERAL_generic
);
752 maker
.put(opAppleGenericAnchor
);
759 name
=identifierString();
760 maker
.put(opNamedAnchor
); maker
.put(name
);
765 throw antlr::NoViableAltException(LT(1), getFilename());
769 catch (antlr::RecognitionException
& ex
) {
771 recover(ex
,_tokenSet_9
);
775 int32_t RequirementParser::certSlot() {
778 try { // for error handling
795 slot
= Requirement::leafCert
;
801 slot
= Requirement::anchorCert
;
806 throw antlr::NoViableAltException(LT(1), getFilename());
810 catch (antlr::RecognitionException
& ex
) {
812 recover(ex
,_tokenSet_13
);
817 void RequirementParser::certslotspec(
818 Maker
&maker
, int32_t slot
822 try { // for error handling
833 certificateDigest(digest
);
834 maker
.anchor(slot
, digest
);
840 certMatchOperation(maker
, slot
, key
);
846 throw antlr::NoViableAltException(LT(1), getFilename());
850 catch (antlr::RecognitionException
& ex
) {
852 recover(ex
,_tokenSet_9
);
856 void RequirementParser::empty() {
858 try { // for error handling
860 catch (antlr::RecognitionException
& ex
) {
862 recover(ex
,_tokenSet_14
);
866 void RequirementParser::certificateDigest(
870 try { // for error handling
883 if (CFRef
<CFDataRef
> certData
= cfLoadFile(path
))
884 hashOfCertificate(CFDataGetBytePtr(certData
), CFDataGetLength(certData
), digest
);
886 throw antlr::SemanticException(path
+ ": not found");
892 throw antlr::NoViableAltException(LT(1), getFilename());
896 catch (antlr::RecognitionException
& ex
) {
898 recover(ex
,_tokenSet_9
);
902 string
RequirementParser::bracketKey() {
905 try { // for error handling
910 catch (antlr::RecognitionException
& ex
) {
912 recover(ex
,_tokenSet_15
);
917 void RequirementParser::match_suffix(
921 try { // for error handling
923 case antlr::Token::EOF_TYPE
:
926 case LITERAL_designated
:
927 case LITERAL_library
:
941 match(LITERAL_exists
);
944 case antlr::Token::EOF_TYPE
:
947 case LITERAL_designated
:
948 case LITERAL_library
:
960 throw antlr::NoViableAltException(LT(1), getFilename());
964 maker
.put(matchExists
);
984 throw antlr::NoViableAltException(LT(1), getFilename());
988 MatchOperation mop
= matchEqual
; string value
;
1005 throw antlr::NoViableAltException(LT(1), getFilename());
1015 mop
= (mop
== matchEndsWith
) ? matchContains
: matchBeginsWith
;
1018 case antlr::Token::EOF_TYPE
:
1021 case LITERAL_designated
:
1022 case LITERAL_library
:
1023 case LITERAL_plugin
:
1034 throw antlr::NoViableAltException(LT(1), getFilename());
1038 maker
.put(mop
); maker
.put(value
);
1046 maker
.put(matchContains
); maker
.put(value
);
1054 maker
.put(matchLessThan
); maker
.put(value
);
1062 maker
.put(matchGreaterThan
); maker
.put(value
);
1070 maker
.put(matchLessEqual
); maker
.put(value
);
1078 maker
.put(matchGreaterEqual
); maker
.put(value
);
1083 throw antlr::NoViableAltException(LT(1), getFilename());
1087 catch (antlr::RecognitionException
& ex
) {
1089 recover(ex
,_tokenSet_9
);
1093 string
RequirementParser::datavalue() {
1095 antlr::RefToken hex
= antlr::nullToken
;
1097 try { // for error handling
1102 result
=stringvalue();
1109 result
= hexString(hex
->getText());
1114 throw antlr::NoViableAltException(LT(1), getFilename());
1118 catch (antlr::RecognitionException
& ex
) {
1120 recover(ex
,_tokenSet_16
);
1125 string
RequirementParser::stringvalue() {
1127 antlr::RefToken dk
= antlr::nullToken
;
1128 antlr::RefToken s
= antlr::nullToken
;
1130 try { // for error handling
1136 result
= dk
->getText();
1143 result
= s
->getText();
1148 throw antlr::NoViableAltException(LT(1), getFilename());
1152 catch (antlr::RecognitionException
& ex
) {
1154 recover(ex
,_tokenSet_17
);
1159 string
RequirementParser::pathstring() {
1161 antlr::RefToken dk
= antlr::nullToken
;
1162 antlr::RefToken s
= antlr::nullToken
;
1163 antlr::RefToken pn
= antlr::nullToken
;
1165 try { // for error handling
1171 result
= dk
->getText();
1178 result
= s
->getText();
1185 result
= pn
->getText();
1190 throw antlr::NoViableAltException(LT(1), getFilename());
1194 catch (antlr::RecognitionException
& ex
) {
1196 recover(ex
,_tokenSet_9
);
1201 void RequirementParser::initializeASTFactory( antlr::ASTFactory
& )
1204 const char* RequirementParser::tokenNames
[] = {
1208 "NULL_TREE_LOOKAHEAD",
1266 const unsigned long RequirementParser::_tokenSet_0_data_
[] = { 2UL, 0UL, 0UL, 0UL };
1268 const antlr::BitSet
RequirementParser::_tokenSet_0(_tokenSet_0_data_
,4);
1269 const unsigned long RequirementParser::_tokenSet_1_data_
[] = { 992UL, 131072UL, 0UL, 0UL };
1270 // "guest" "host" "designated" "library" "plugin" INTEGER
1271 const antlr::BitSet
RequirementParser::_tokenSet_1(_tokenSet_1_data_
,4);
1272 const unsigned long RequirementParser::_tokenSet_2_data_
[] = { 16UL, 0UL, 0UL, 0UL };
1274 const antlr::BitSet
RequirementParser::_tokenSet_2(_tokenSet_2_data_
,4);
1275 const unsigned long RequirementParser::_tokenSet_3_data_
[] = { 994UL, 131072UL, 0UL, 0UL };
1276 // EOF "guest" "host" "designated" "library" "plugin" INTEGER
1277 const antlr::BitSet
RequirementParser::_tokenSet_3(_tokenSet_3_data_
,4);
1278 const unsigned long RequirementParser::_tokenSet_4_data_
[] = { 2281713650UL, 512129UL, 0UL, 0UL };
1279 // EOF ARROW "guest" "host" "designated" "library" "plugin" "or" "and"
1280 // RPAREN "trusted" EQL EQQL LBRACK HASHCONSTANT DOTKEY STRING PATHNAME
1282 const antlr::BitSet
RequirementParser::_tokenSet_4(_tokenSet_4_data_
,4);
1283 const unsigned long RequirementParser::_tokenSet_5_data_
[] = { 9186UL, 393216UL, 0UL, 0UL };
1284 // EOF "guest" "host" "designated" "library" "plugin" RPAREN INTEGER SEMI
1285 const antlr::BitSet
RequirementParser::_tokenSet_5(_tokenSet_5_data_
,4);
1286 const unsigned long RequirementParser::_tokenSet_6_data_
[] = { 994UL, 393216UL, 0UL, 0UL };
1287 // EOF "guest" "host" "designated" "library" "plugin" INTEGER SEMI
1288 const antlr::BitSet
RequirementParser::_tokenSet_6(_tokenSet_6_data_
,4);
1289 const unsigned long RequirementParser::_tokenSet_7_data_
[] = { 10210UL, 393216UL, 0UL, 0UL };
1290 // EOF "guest" "host" "designated" "library" "plugin" "or" RPAREN INTEGER
1292 const antlr::BitSet
RequirementParser::_tokenSet_7(_tokenSet_7_data_
,4);
1293 const unsigned long RequirementParser::_tokenSet_8_data_
[] = { 914345984UL, 0UL, 0UL, 0UL };
1294 // LPAREN NOT "always" "true" "never" "false" "identifier" "cdhash" "platform"
1295 // "anchor" "certificate" "cert" "info" "entitlement"
1296 const antlr::BitSet
RequirementParser::_tokenSet_8(_tokenSet_8_data_
,4);
1297 const unsigned long RequirementParser::_tokenSet_9_data_
[] = { 12258UL, 393216UL, 0UL, 0UL };
1298 // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN
1300 const antlr::BitSet
RequirementParser::_tokenSet_9(_tokenSet_9_data_
,4);
1301 const unsigned long RequirementParser::_tokenSet_10_data_
[] = { 0UL, 134656UL, 0UL, 0UL };
1302 // NEG "leaf" "root" INTEGER
1303 const antlr::BitSet
RequirementParser::_tokenSet_10(_tokenSet_10_data_
,4);
1304 const unsigned long RequirementParser::_tokenSet_11_data_
[] = { 2147483648UL, 118913UL, 0UL, 0UL };
1305 // EQL EQQL LBRACK HASHCONSTANT DOTKEY STRING PATHNAME
1306 const antlr::BitSet
RequirementParser::_tokenSet_11(_tokenSet_11_data_
,4);
1307 const unsigned long RequirementParser::_tokenSet_12_data_
[] = { 0UL, 249856UL, 0UL, 0UL };
1308 // HASHCONSTANT DOTKEY STRING PATHNAME INTEGER
1309 const antlr::BitSet
RequirementParser::_tokenSet_12(_tokenSet_12_data_
,4);
1310 const unsigned long RequirementParser::_tokenSet_13_data_
[] = { 2281701376UL, 118913UL, 0UL, 0UL };
1311 // "trusted" EQL EQQL LBRACK HASHCONSTANT DOTKEY STRING PATHNAME
1312 const antlr::BitSet
RequirementParser::_tokenSet_13(_tokenSet_13_data_
,4);
1313 const unsigned long RequirementParser::_tokenSet_14_data_
[] = { 1073754082UL, 512000UL, 0UL, 0UL };
1314 // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN
1315 // "exists" HASHCONSTANT DOTKEY STRING PATHNAME INTEGER SEMI
1316 const antlr::BitSet
RequirementParser::_tokenSet_14(_tokenSet_14_data_
,4);
1317 const unsigned long RequirementParser::_tokenSet_15_data_
[] = { 3221237730UL, 393341UL, 0UL, 0UL };
1318 // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN
1319 // "exists" EQL EQQL SUBS LESS GT LE GE INTEGER SEMI
1320 const antlr::BitSet
RequirementParser::_tokenSet_15(_tokenSet_15_data_
,4);
1321 const unsigned long RequirementParser::_tokenSet_16_data_
[] = { 12258UL, 393218UL, 0UL, 0UL };
1322 // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN
1323 // STAR INTEGER SEMI
1324 const antlr::BitSet
RequirementParser::_tokenSet_16(_tokenSet_16_data_
,4);
1325 const unsigned long RequirementParser::_tokenSet_17_data_
[] = { 12258UL, 393474UL, 0UL, 0UL };
1326 // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN
1327 // STAR RBRACK INTEGER SEMI
1328 const antlr::BitSet
RequirementParser::_tokenSet_17(_tokenSet_17_data_
,4);