/ OSX / libsecurity_codesigning / lib / RequirementParser.cpp
RequirementParser.cpp
   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>
   6  
   7  #include "requirement.h"
   8  #include "reqmaker.h"
   9  #include "csutilities.h"
  10  #include <libDER/libDER.h>
  11  #include <libDER/asn1Types.h>
  12  #include <security_utilities/cfutilities.h>
  13  #include <security_utilities/hashing.h>
  14  #include <security_cdsa_utilities/cssmdata.h>	// OID coding
  15  #include <Security/SecCertificate.h>
  16  using namespace CodeSigning;
  17  typedef Requirement::Maker Maker;
  18  
  19  extern "C" {
  20  
  21  /* Decode a choice of UTCTime or GeneralizedTime to a CFAbsoluteTime. Return
  22  an absoluteTime if the date was valid and properly decoded.  Return
  23  NULL_TIME otherwise. */
  24  CFAbsoluteTime SecAbsoluteTimeFromDateContent(DERTag tag, const uint8_t *bytes,
  25  	size_t length);
  26  
  27  }
  28  
  29  
  30  ANTLR_BEGIN_NAMESPACE(Security_CodeSigning)
  31  
  32  	//
  33  	// Collect error messages.
  34  	// Note that the immediate caller takes the absence of collected error messages
  35  	// to indicate compilation success.
  36  	//
  37  	void RequirementParser::reportError(const antlr::RecognitionException &ex)
  38  	{
  39  		errors += ex.toString() + "\n";
  40  	}
  41  	
  42  	void RequirementParser::reportError(const std::string &s)
  43  	{
  44  		errors += s + "\n";
  45  	}
  46  
  47  	
  48  	//
  49  	// Parser helper functions
  50  	//
  51  	string RequirementParser::hexString(const string &s)
  52  	{
  53  		if (s.size() % 2)
  54  			throw antlr::SemanticException("odd number of digits");
  55  		const char *p = s.data();
  56  		string result;
  57  		for (unsigned n = 0; n < s.length(); n += 2) {
  58  			char c;
  59  			sscanf(p+n, "%2hhx", &c);
  60  			result.push_back(c);
  61  		}
  62  		return result;
  63  	}
  64  
  65  	void RequirementParser::hashString(const string &s, SHA1::Digest hash)
  66  	{
  67  		if (s.size() != 2 * SHA1::digestLength)
  68  			throw antlr::SemanticException("invalid hash length");
  69  		memcpy(hash, hexString(s).data(), SHA1::digestLength);
  70  	}
  71  	
  72  	static const char *matchPrefix(const string &key, const char *prefix)
  73  	{
  74  		size_t pLength = strlen(prefix);
  75  		if (!key.compare(0, pLength, prefix, 0, pLength))
  76  			return key.c_str() + pLength;
  77  		else
  78  			return NULL;
  79  	}
  80  	
  81  	void RequirementParser::certMatchOperation(Maker &maker, int32_t slot, string key)
  82  	{
  83  		if (const char *oids = matchPrefix(key, "timestamp.")) {
  84  			maker.put(opCertFieldDate);
  85  			maker.put(slot);
  86  			CssmAutoData oid(Allocator::standard()); oid.fromOid(oids);
  87  			maker.putData(oid.data(), oid.length());
  88  		} else if (matchPrefix(key, "subject.")) {
  89  			maker.put(opCertField);
  90  			maker.put(slot);
  91  			maker.put(key);
  92  		} else if (const char *oids = matchPrefix(key, "field.")) {
  93  			maker.put(opCertGeneric);
  94  			maker.put(slot);
  95  			CssmAutoData oid(Allocator::standard()); oid.fromOid(oids);
  96  			maker.putData(oid.data(), oid.length());
  97  		} else if (const char *oids = matchPrefix(key, "extension.")) {
  98  			maker.put(opCertGeneric);
  99  			maker.put(slot);
 100  			CssmAutoData oid(Allocator::standard()); oid.fromOid(oids);
 101  			maker.putData(oid.data(), oid.length());
 102  		} else if (const char *oids = matchPrefix(key, "policy.")) {
 103  			maker.put(opCertPolicy);
 104  			maker.put(slot);
 105  			CssmAutoData oid(Allocator::standard()); oid.fromOid(oids);
 106  			maker.putData(oid.data(), oid.length());
 107  		} else {
 108  			throw antlr::SemanticException(key + ": unrecognized certificate field");
 109  		}
 110  	}
 111  
 112  RequirementParser::RequirementParser(antlr::TokenBuffer& tokenBuf, int k)
 113  : antlr::LLkParser(tokenBuf,k)
 114  {
 115  }
 116  
 117  RequirementParser::RequirementParser(antlr::TokenBuffer& tokenBuf)
 118  : antlr::LLkParser(tokenBuf,2)
 119  {
 120  }
 121  
 122  RequirementParser::RequirementParser(antlr::TokenStream& lexer, int k)
 123  : antlr::LLkParser(lexer,k)
 124  {
 125  }
 126  
 127  RequirementParser::RequirementParser(antlr::TokenStream& lexer)
 128  : antlr::LLkParser(lexer,2)
 129  {
 130  }
 131  
 132  RequirementParser::RequirementParser(const antlr::ParserSharedInputState& state)
 133  : antlr::LLkParser(state,2)
 134  {
 135  }
 136  
 137  BlobCore * RequirementParser::autosense() {
 138  	BlobCore *result = NULL;
 139  	
 140  	try {      // for error handling
 141  		switch ( LA(1)) {
 142  		case LPAREN:
 143  		case NOT:
 144  		case LITERAL_always:
 145  		case LITERAL_true:
 146  		case LITERAL_never:
 147  		case LITERAL_false:
 148  		case LITERAL_identifier:
 149  		case LITERAL_cdhash:
 150  		case LITERAL_platform:
 151  		case LITERAL_notarized:
 152  		case LITERAL_legacy:
 153  		case LITERAL_anchor:
 154  		case LITERAL_certificate:
 155  		case LITERAL_cert:
 156  		case LITERAL_info:
 157  		case LITERAL_entitlement:
 158  		{
 159  			result=requirement();
 160  			break;
 161  		}
 162  		case LITERAL_guest:
 163  		case LITERAL_host:
 164  		case LITERAL_designated:
 165  		case LITERAL_library:
 166  		case LITERAL_plugin:
 167  		case INTEGER:
 168  		{
 169  			result=requirementSet();
 170  			break;
 171  		}
 172  		default:
 173  		{
 174  			throw antlr::NoViableAltException(LT(1), getFilename());
 175  		}
 176  		}
 177  	}
 178  	catch (antlr::RecognitionException& ex) {
 179  		reportError(ex);
 180  		recover(ex,_tokenSet_0);
 181  	}
 182  	return result;
 183  }
 184  
 185  Requirement * RequirementParser::requirement() {
 186  	Requirement *result = NULL;
 187  	
 188  	try {      // for error handling
 189  		result=requirementElement();
 190  		match(antlr::Token::EOF_TYPE);
 191  	}
 192  	catch (antlr::RecognitionException& ex) {
 193  		reportError(ex);
 194  		recover(ex,_tokenSet_0);
 195  	}
 196  	return result;
 197  }
 198  
 199  Requirements * RequirementParser::requirementSet() {
 200  	Requirements *result = NULL;
 201  	Requirements::Maker maker;
 202  	
 203  	try {      // for error handling
 204  		{ // ( ... )+
 205  		int _cnt4=0;
 206  		for (;;) {
 207  			if ((_tokenSet_1.member(LA(1)))) {
 208  				uint32_t t; Requirement *req;
 209  				t=requirementType();
 210  				match(ARROW);
 211  				req=requirementElement();
 212  				maker.add(t, req);
 213  			}
 214  			else {
 215  				if ( _cnt4>=1 ) { goto _loop4; } else {throw antlr::NoViableAltException(LT(1), getFilename());}
 216  			}
 217  			
 218  			_cnt4++;
 219  		}
 220  		_loop4:;
 221  		}  // ( ... )+
 222  		result = errors.empty() ? maker() : NULL;
 223  		match(antlr::Token::EOF_TYPE);
 224  	}
 225  	catch (antlr::RecognitionException& ex) {
 226  		reportError(ex);
 227  		recover(ex,_tokenSet_0);
 228  	}
 229  	return result;
 230  }
 231  
 232  uint32_t  RequirementParser::requirementType() {
 233  	uint32_t type = kSecInvalidRequirementType;
 234  	
 235  	try {      // for error handling
 236  		switch ( LA(1)) {
 237  		case LITERAL_guest:
 238  		{
 239  			match(LITERAL_guest);
 240  			type = kSecGuestRequirementType;
 241  			break;
 242  		}
 243  		case LITERAL_host:
 244  		{
 245  			match(LITERAL_host);
 246  			type = kSecHostRequirementType;
 247  			break;
 248  		}
 249  		case LITERAL_designated:
 250  		{
 251  			match(LITERAL_designated);
 252  			type = kSecDesignatedRequirementType;
 253  			break;
 254  		}
 255  		case LITERAL_library:
 256  		{
 257  			match(LITERAL_library);
 258  			type = kSecLibraryRequirementType;
 259  			break;
 260  		}
 261  		case LITERAL_plugin:
 262  		{
 263  			match(LITERAL_plugin);
 264  			type = kSecPluginRequirementType;
 265  			break;
 266  		}
 267  		case INTEGER:
 268  		{
 269  			type=integer();
 270  			break;
 271  		}
 272  		default:
 273  		{
 274  			throw antlr::NoViableAltException(LT(1), getFilename());
 275  		}
 276  		}
 277  	}
 278  	catch (antlr::RecognitionException& ex) {
 279  		reportError(ex);
 280  		recover(ex,_tokenSet_2);
 281  	}
 282  	return type;
 283  }
 284  
 285  Requirement * RequirementParser::requirementElement() {
 286  	Requirement *result = NULL;
 287  	Requirement::Maker maker;
 288  	
 289  	try {      // for error handling
 290  		expr(maker);
 291  		result = maker();
 292  		{ // ( ... )*
 293  		for (;;) {
 294  			if ((LA(1) == SEMI)) {
 295  				fluff();
 296  			}
 297  			else {
 298  				goto _loop9;
 299  			}
 300  			
 301  		}
 302  		_loop9:;
 303  		} // ( ... )*
 304  	}
 305  	catch (antlr::RecognitionException& ex) {
 306  		reportError(ex);
 307  		recover(ex,_tokenSet_3);
 308  	}
 309  	return result;
 310  }
 311  
 312  int32_t  RequirementParser::integer() {
 313  	int32_t result;
 314  	antlr::RefToken  s = antlr::nullToken;
 315  	
 316  	try {      // for error handling
 317  		s = LT(1);
 318  		match(INTEGER);
 319  		result = int32_t(atol(s->getText().c_str()));
 320  	}
 321  	catch (antlr::RecognitionException& ex) {
 322  		reportError(ex);
 323  		recover(ex,_tokenSet_4);
 324  	}
 325  	return result;
 326  }
 327  
 328  void RequirementParser::expr(
 329  	Maker &maker
 330  ) {
 331  	Maker::Label label(maker);
 332  	
 333  	try {      // for error handling
 334  		term(maker);
 335  		{ // ( ... )*
 336  		for (;;) {
 337  			if ((LA(1) == LITERAL_or)) {
 338  				match(LITERAL_or);
 339  				maker.insert<ExprOp>(label) = opOr;
 340  				term(maker);
 341  			}
 342  			else {
 343  				goto _loop12;
 344  			}
 345  			
 346  		}
 347  		_loop12:;
 348  		} // ( ... )*
 349  	}
 350  	catch (antlr::RecognitionException& ex) {
 351  		reportError(ex);
 352  		recover(ex,_tokenSet_5);
 353  	}
 354  }
 355  
 356  void RequirementParser::fluff() {
 357  	
 358  	try {      // for error handling
 359  		match(SEMI);
 360  	}
 361  	catch (antlr::RecognitionException& ex) {
 362  		reportError(ex);
 363  		recover(ex,_tokenSet_6);
 364  	}
 365  }
 366  
 367  void RequirementParser::term(
 368  	Maker &maker
 369  ) {
 370  	Maker::Label label(maker);
 371  	
 372  	try {      // for error handling
 373  		primary(maker);
 374  		{ // ( ... )*
 375  		for (;;) {
 376  			if ((LA(1) == LITERAL_and)) {
 377  				match(LITERAL_and);
 378  				maker.insert<ExprOp>(label) = opAnd;
 379  				primary(maker);
 380  			}
 381  			else {
 382  				goto _loop15;
 383  			}
 384  			
 385  		}
 386  		_loop15:;
 387  		} // ( ... )*
 388  	}
 389  	catch (antlr::RecognitionException& ex) {
 390  		reportError(ex);
 391  		recover(ex,_tokenSet_7);
 392  	}
 393  }
 394  
 395  void RequirementParser::primary(
 396  	Maker &maker
 397  ) {
 398  	
 399  	try {      // for error handling
 400  		switch ( LA(1)) {
 401  		case NOT:
 402  		{
 403  			match(NOT);
 404  			maker.put(opNot);
 405  			primary(maker);
 406  			break;
 407  		}
 408  		case LITERAL_always:
 409  		case LITERAL_true:
 410  		{
 411  			{
 412  			switch ( LA(1)) {
 413  			case LITERAL_always:
 414  			{
 415  				match(LITERAL_always);
 416  				break;
 417  			}
 418  			case LITERAL_true:
 419  			{
 420  				match(LITERAL_true);
 421  				break;
 422  			}
 423  			default:
 424  			{
 425  				throw antlr::NoViableAltException(LT(1), getFilename());
 426  			}
 427  			}
 428  			}
 429  			maker.put(opTrue);
 430  			break;
 431  		}
 432  		case LITERAL_never:
 433  		case LITERAL_false:
 434  		{
 435  			{
 436  			switch ( LA(1)) {
 437  			case LITERAL_never:
 438  			{
 439  				match(LITERAL_never);
 440  				break;
 441  			}
 442  			case LITERAL_false:
 443  			{
 444  				match(LITERAL_false);
 445  				break;
 446  			}
 447  			default:
 448  			{
 449  				throw antlr::NoViableAltException(LT(1), getFilename());
 450  			}
 451  			}
 452  			}
 453  			maker.put(opFalse);
 454  			break;
 455  		}
 456  		case LITERAL_anchor:
 457  		case LITERAL_certificate:
 458  		case LITERAL_cert:
 459  		{
 460  			certspec(maker);
 461  			break;
 462  		}
 463  		case LITERAL_info:
 464  		{
 465  			infospec(maker);
 466  			break;
 467  		}
 468  		case LITERAL_entitlement:
 469  		{
 470  			entitlementspec(maker);
 471  			break;
 472  		}
 473  		case LITERAL_identifier:
 474  		{
 475  			match(LITERAL_identifier);
 476  			string code;
 477  			eql();
 478  			code=identifierString();
 479  			maker.ident(code);
 480  			break;
 481  		}
 482  		case LITERAL_cdhash:
 483  		{
 484  			match(LITERAL_cdhash);
 485  			SHA1::Digest digest;
 486  			eql();
 487  			hash(digest);
 488  			maker.cdhash(digest);
 489  			break;
 490  		}
 491  		case LITERAL_platform:
 492  		{
 493  			match(LITERAL_platform);
 494  			int32_t ident;
 495  			eql();
 496  			ident=integer();
 497  			maker.platform(ident);
 498  			break;
 499  		}
 500  		case LITERAL_notarized:
 501  		{
 502  			match(LITERAL_notarized);
 503  			maker.put(opNotarized);
 504  			break;
 505  		}
 506  		case LITERAL_legacy:
 507  		{
 508  			match(LITERAL_legacy);
 509  			maker.put(opLegacyDevID);
 510  			break;
 511  		}
 512  		default:
 513  			if ((LA(1) == LPAREN) && (_tokenSet_8.member(LA(2)))) {
 514  				match(LPAREN);
 515  				expr(maker);
 516  				match(RPAREN);
 517  			}
 518  			else if ((LA(1) == LPAREN) && (LA(2) == DOTKEY || LA(2) == STRING)) {
 519  				match(LPAREN);
 520  				string name;
 521  				name=identifierString();
 522  				match(RPAREN);
 523  				maker.put(opNamedCode); maker.put(name);
 524  			}
 525  		else {
 526  			throw antlr::NoViableAltException(LT(1), getFilename());
 527  		}
 528  		}
 529  	}
 530  	catch (antlr::RecognitionException& ex) {
 531  		reportError(ex);
 532  		recover(ex,_tokenSet_9);
 533  	}
 534  }
 535  
 536  void RequirementParser::certspec(
 537  	Maker &maker
 538  ) {
 539  	
 540  	try {      // for error handling
 541  		if ((LA(1) == LITERAL_anchor) && (LA(2) == LITERAL_apple)) {
 542  			match(LITERAL_anchor);
 543  			match(LITERAL_apple);
 544  			appleanchor(maker);
 545  		}
 546  		else if ((LA(1) == LITERAL_anchor) && (LA(2) == LITERAL_generic)) {
 547  			match(LITERAL_anchor);
 548  			match(LITERAL_generic);
 549  			match(LITERAL_apple);
 550  			maker.put(opAppleGenericAnchor);
 551  		}
 552  		else if ((LA(1) == LITERAL_anchor || LA(1) == LITERAL_certificate || LA(1) == LITERAL_cert) && (LA(2) == LITERAL_trusted)) {
 553  			{
 554  			switch ( LA(1)) {
 555  			case LITERAL_certificate:
 556  			{
 557  				match(LITERAL_certificate);
 558  				break;
 559  			}
 560  			case LITERAL_cert:
 561  			{
 562  				match(LITERAL_cert);
 563  				break;
 564  			}
 565  			case LITERAL_anchor:
 566  			{
 567  				match(LITERAL_anchor);
 568  				break;
 569  			}
 570  			default:
 571  			{
 572  				throw antlr::NoViableAltException(LT(1), getFilename());
 573  			}
 574  			}
 575  			}
 576  			match(LITERAL_trusted);
 577  			maker.trustedAnchor();
 578  		}
 579  		else if ((LA(1) == LITERAL_certificate || LA(1) == LITERAL_cert) && (_tokenSet_10.member(LA(2)))) {
 580  			{
 581  			switch ( LA(1)) {
 582  			case LITERAL_certificate:
 583  			{
 584  				match(LITERAL_certificate);
 585  				break;
 586  			}
 587  			case LITERAL_cert:
 588  			{
 589  				match(LITERAL_cert);
 590  				break;
 591  			}
 592  			default:
 593  			{
 594  				throw antlr::NoViableAltException(LT(1), getFilename());
 595  			}
 596  			}
 597  			}
 598  			int32_t slot;
 599  			slot=certSlot();
 600  			{
 601  			switch ( LA(1)) {
 602  			case EQL:
 603  			case EQQL:
 604  			case LBRACK:
 605  			case HASHCONSTANT:
 606  			case DOTKEY:
 607  			case STRING:
 608  			case PATHNAME:
 609  			{
 610  				certslotspec(maker, slot);
 611  				break;
 612  			}
 613  			case LITERAL_trusted:
 614  			{
 615  				match(LITERAL_trusted);
 616  				maker.trustedAnchor(slot);
 617  				break;
 618  			}
 619  			default:
 620  			{
 621  				throw antlr::NoViableAltException(LT(1), getFilename());
 622  			}
 623  			}
 624  			}
 625  		}
 626  		else if ((LA(1) == LITERAL_anchor) && (_tokenSet_11.member(LA(2)))) {
 627  			match(LITERAL_anchor);
 628  			certslotspec(maker, Requirement::anchorCert);
 629  		}
 630  		else {
 631  			throw antlr::NoViableAltException(LT(1), getFilename());
 632  		}
 633  		
 634  	}
 635  	catch (antlr::RecognitionException& ex) {
 636  		reportError(ex);
 637  		recover(ex,_tokenSet_9);
 638  	}
 639  }
 640  
 641  void RequirementParser::infospec(
 642  	Maker &maker
 643  ) {
 644  	string key;
 645  	
 646  	try {      // for error handling
 647  		match(LITERAL_info);
 648  		key=bracketKey();
 649  		maker.put(opInfoKeyField); maker.put(key);
 650  		match_suffix(maker);
 651  	}
 652  	catch (antlr::RecognitionException& ex) {
 653  		reportError(ex);
 654  		recover(ex,_tokenSet_9);
 655  	}
 656  }
 657  
 658  void RequirementParser::entitlementspec(
 659  	Maker &maker
 660  ) {
 661  	string key;
 662  	
 663  	try {      // for error handling
 664  		match(LITERAL_entitlement);
 665  		key=bracketKey();
 666  		maker.put(opEntitlementField); maker.put(key);
 667  		match_suffix(maker);
 668  	}
 669  	catch (antlr::RecognitionException& ex) {
 670  		reportError(ex);
 671  		recover(ex,_tokenSet_9);
 672  	}
 673  }
 674  
 675  void RequirementParser::eql() {
 676  	
 677  	try {      // for error handling
 678  		switch ( LA(1)) {
 679  		case EQL:
 680  		{
 681  			match(EQL);
 682  			break;
 683  		}
 684  		case EQQL:
 685  		{
 686  			match(EQQL);
 687  			break;
 688  		}
 689  		case HASHCONSTANT:
 690  		case DOTKEY:
 691  		case STRING:
 692  		case PATHNAME:
 693  		case INTEGER:
 694  		{
 695  			empty();
 696  			break;
 697  		}
 698  		default:
 699  		{
 700  			throw antlr::NoViableAltException(LT(1), getFilename());
 701  		}
 702  		}
 703  	}
 704  	catch (antlr::RecognitionException& ex) {
 705  		reportError(ex);
 706  		recover(ex,_tokenSet_12);
 707  	}
 708  }
 709  
 710  string  RequirementParser::identifierString() {
 711  	string result;
 712  	antlr::RefToken  dk = antlr::nullToken;
 713  	antlr::RefToken  s = antlr::nullToken;
 714  	
 715  	try {      // for error handling
 716  		switch ( LA(1)) {
 717  		case DOTKEY:
 718  		{
 719  			dk = LT(1);
 720  			match(DOTKEY);
 721  			result = dk->getText();
 722  			break;
 723  		}
 724  		case STRING:
 725  		{
 726  			s = LT(1);
 727  			match(STRING);
 728  			result = s->getText();
 729  			break;
 730  		}
 731  		default:
 732  		{
 733  			throw antlr::NoViableAltException(LT(1), getFilename());
 734  		}
 735  		}
 736  	}
 737  	catch (antlr::RecognitionException& ex) {
 738  		reportError(ex);
 739  		recover(ex,_tokenSet_9);
 740  	}
 741  	return result;
 742  }
 743  
 744  void RequirementParser::hash(
 745  	SHA1::Digest digest
 746  ) {
 747  	antlr::RefToken  hash = antlr::nullToken;
 748  	
 749  	try {      // for error handling
 750  		hash = LT(1);
 751  		match(HASHCONSTANT);
 752  		hashString(hash->getText(), digest);
 753  	}
 754  	catch (antlr::RecognitionException& ex) {
 755  		reportError(ex);
 756  		recover(ex,_tokenSet_9);
 757  	}
 758  }
 759  
 760  void RequirementParser::appleanchor(
 761  	Maker &maker
 762  ) {
 763  	
 764  	try {      // for error handling
 765  		switch ( LA(1)) {
 766  		case antlr::Token::EOF_TYPE:
 767  		case LITERAL_guest:
 768  		case LITERAL_host:
 769  		case LITERAL_designated:
 770  		case LITERAL_library:
 771  		case LITERAL_plugin:
 772  		case LITERAL_or:
 773  		case LITERAL_and:
 774  		case RPAREN:
 775  		case INTEGER:
 776  		case SEMI:
 777  		{
 778  			empty();
 779  			maker.put(opAppleAnchor);
 780  			break;
 781  		}
 782  		case LITERAL_generic:
 783  		{
 784  			match(LITERAL_generic);
 785  			maker.put(opAppleGenericAnchor);
 786  			break;
 787  		}
 788  		case DOTKEY:
 789  		case STRING:
 790  		{
 791  			string name;
 792  			name=identifierString();
 793  			maker.put(opNamedAnchor); maker.put(name);
 794  			break;
 795  		}
 796  		default:
 797  		{
 798  			throw antlr::NoViableAltException(LT(1), getFilename());
 799  		}
 800  		}
 801  	}
 802  	catch (antlr::RecognitionException& ex) {
 803  		reportError(ex);
 804  		recover(ex,_tokenSet_9);
 805  	}
 806  }
 807  
 808  int32_t  RequirementParser::certSlot() {
 809  	int32_t slot = 0;
 810  	
 811  	try {      // for error handling
 812  		switch ( LA(1)) {
 813  		case INTEGER:
 814  		{
 815  			slot=integer();
 816  			break;
 817  		}
 818  		case NEG:
 819  		{
 820  			match(NEG);
 821  			slot=integer();
 822  			slot = -slot;
 823  			break;
 824  		}
 825  		case LITERAL_leaf:
 826  		{
 827  			match(LITERAL_leaf);
 828  			slot = Requirement::leafCert;
 829  			break;
 830  		}
 831  		case LITERAL_root:
 832  		{
 833  			match(LITERAL_root);
 834  			slot = Requirement::anchorCert;
 835  			break;
 836  		}
 837  		default:
 838  		{
 839  			throw antlr::NoViableAltException(LT(1), getFilename());
 840  		}
 841  		}
 842  	}
 843  	catch (antlr::RecognitionException& ex) {
 844  		reportError(ex);
 845  		recover(ex,_tokenSet_13);
 846  	}
 847  	return slot;
 848  }
 849  
 850  void RequirementParser::certslotspec(
 851  	Maker &maker, int32_t slot
 852  ) {
 853  	string key;
 854  	
 855  	try {      // for error handling
 856  		switch ( LA(1)) {
 857  		case EQL:
 858  		case EQQL:
 859  		case HASHCONSTANT:
 860  		case DOTKEY:
 861  		case STRING:
 862  		case PATHNAME:
 863  		{
 864  			eql();
 865  			SHA1::Digest digest;
 866  			certificateDigest(digest);
 867  			maker.anchor(slot, digest);
 868  			break;
 869  		}
 870  		case LBRACK:
 871  		{
 872  			key=bracketKey();
 873  			certMatchOperation(maker, slot, key);
 874  			match_suffix(maker);
 875  			break;
 876  		}
 877  		default:
 878  		{
 879  			throw antlr::NoViableAltException(LT(1), getFilename());
 880  		}
 881  		}
 882  	}
 883  	catch (antlr::RecognitionException& ex) {
 884  		reportError(ex);
 885  		recover(ex,_tokenSet_9);
 886  	}
 887  }
 888  
 889  void RequirementParser::empty() {
 890  	
 891  	try {      // for error handling
 892  	}
 893  	catch (antlr::RecognitionException& ex) {
 894  		reportError(ex);
 895  		recover(ex,_tokenSet_14);
 896  	}
 897  }
 898  
 899  void RequirementParser::certificateDigest(
 900  	SHA1::Digest digest
 901  ) {
 902  	
 903  	try {      // for error handling
 904  		switch ( LA(1)) {
 905  		case HASHCONSTANT:
 906  		{
 907  			hash(digest);
 908  			break;
 909  		}
 910  		case DOTKEY:
 911  		case STRING:
 912  		case PATHNAME:
 913  		{
 914  			string path;
 915  			path=pathstring();
 916  			if (CFRef<CFDataRef> certData = cfLoadFile(path))
 917  							hashOfCertificate(CFDataGetBytePtr(certData), CFDataGetLength(certData), digest);
 918  						  else
 919  							throw antlr::SemanticException(path + ": not found");
 920  						
 921  			break;
 922  		}
 923  		default:
 924  		{
 925  			throw antlr::NoViableAltException(LT(1), getFilename());
 926  		}
 927  		}
 928  	}
 929  	catch (antlr::RecognitionException& ex) {
 930  		reportError(ex);
 931  		recover(ex,_tokenSet_9);
 932  	}
 933  }
 934  
 935  string  RequirementParser::bracketKey() {
 936  	string key;
 937  	
 938  	try {      // for error handling
 939  		match(LBRACK);
 940  		key=stringvalue();
 941  		match(RBRACK);
 942  	}
 943  	catch (antlr::RecognitionException& ex) {
 944  		reportError(ex);
 945  		recover(ex,_tokenSet_15);
 946  	}
 947  	return key;
 948  }
 949  
 950  void RequirementParser::match_suffix(
 951  	Maker &maker
 952  ) {
 953  	
 954  	try {      // for error handling
 955  		switch ( LA(1)) {
 956  		case antlr::Token::EOF_TYPE:
 957  		case LITERAL_guest:
 958  		case LITERAL_host:
 959  		case LITERAL_designated:
 960  		case LITERAL_library:
 961  		case LITERAL_plugin:
 962  		case LITERAL_or:
 963  		case LITERAL_and:
 964  		case RPAREN:
 965  		case LITERAL_exists:
 966  		case INTEGER:
 967  		case SEMI:
 968  		{
 969  			empty();
 970  			{
 971  			switch ( LA(1)) {
 972  			case LITERAL_exists:
 973  			{
 974  				match(LITERAL_exists);
 975  				break;
 976  			}
 977  			case antlr::Token::EOF_TYPE:
 978  			case LITERAL_guest:
 979  			case LITERAL_host:
 980  			case LITERAL_designated:
 981  			case LITERAL_library:
 982  			case LITERAL_plugin:
 983  			case LITERAL_or:
 984  			case LITERAL_and:
 985  			case RPAREN:
 986  			case INTEGER:
 987  			case SEMI:
 988  			{
 989  				break;
 990  			}
 991  			default:
 992  			{
 993  				throw antlr::NoViableAltException(LT(1), getFilename());
 994  			}
 995  			}
 996  			}
 997  			maker.put(matchExists);
 998  			break;
 999  		}
1000  		case LITERAL_absent:
1001  		{
1002  			match(LITERAL_absent);
1003  			maker.put(matchAbsent);
1004  			break;
1005  		}
1006  		case SUBS:
1007  		{
1008  			match(SUBS);
1009  			string value;
1010  			value=datavalue();
1011  			maker.put(matchContains); maker.put(value);
1012  			break;
1013  		}
1014  		default:
1015  			if ((LA(1) == EQL || LA(1) == EQQL) && (_tokenSet_16.member(LA(2)))) {
1016  				{
1017  				switch ( LA(1)) {
1018  				case EQL:
1019  				{
1020  					match(EQL);
1021  					break;
1022  				}
1023  				case EQQL:
1024  				{
1025  					match(EQQL);
1026  					break;
1027  				}
1028  				default:
1029  				{
1030  					throw antlr::NoViableAltException(LT(1), getFilename());
1031  				}
1032  				}
1033  				}
1034  				MatchOperation mop = matchEqual; string value;
1035  				{
1036  				switch ( LA(1)) {
1037  				case STAR:
1038  				{
1039  					match(STAR);
1040  					mop = matchEndsWith;
1041  					break;
1042  				}
1043  				case HEXCONSTANT:
1044  				case DOTKEY:
1045  				case STRING:
1046  				{
1047  					break;
1048  				}
1049  				default:
1050  				{
1051  					throw antlr::NoViableAltException(LT(1), getFilename());
1052  				}
1053  				}
1054  				}
1055  				value=datavalue();
1056  				{
1057  				switch ( LA(1)) {
1058  				case STAR:
1059  				{
1060  					match(STAR);
1061  					mop = (mop == matchEndsWith) ? matchContains : matchBeginsWith;
1062  					break;
1063  				}
1064  				case antlr::Token::EOF_TYPE:
1065  				case LITERAL_guest:
1066  				case LITERAL_host:
1067  				case LITERAL_designated:
1068  				case LITERAL_library:
1069  				case LITERAL_plugin:
1070  				case LITERAL_or:
1071  				case LITERAL_and:
1072  				case RPAREN:
1073  				case INTEGER:
1074  				case SEMI:
1075  				{
1076  					break;
1077  				}
1078  				default:
1079  				{
1080  					throw antlr::NoViableAltException(LT(1), getFilename());
1081  				}
1082  				}
1083  				}
1084  				maker.put(mop); maker.put(value);
1085  			}
1086  			else if ((LA(1) == EQL || LA(1) == EQQL) && (LA(2) == LITERAL_timestamp)) {
1087  				{
1088  				switch ( LA(1)) {
1089  				case EQL:
1090  				{
1091  					match(EQL);
1092  					break;
1093  				}
1094  				case EQQL:
1095  				{
1096  					match(EQQL);
1097  					break;
1098  				}
1099  				default:
1100  				{
1101  					throw antlr::NoViableAltException(LT(1), getFilename());
1102  				}
1103  				}
1104  				}
1105  				MatchOperation mop = matchOn; int64_t value;
1106  				value=timestamp();
1107  				maker.put(mop); maker.put(value);
1108  			}
1109  			else if ((LA(1) == LESS) && ((LA(2) >= HEXCONSTANT && LA(2) <= STRING))) {
1110  				match(LESS);
1111  				string value;
1112  				value=datavalue();
1113  				maker.put(matchLessThan); maker.put(value);
1114  			}
1115  			else if ((LA(1) == GT) && ((LA(2) >= HEXCONSTANT && LA(2) <= STRING))) {
1116  				match(GT);
1117  				string value;
1118  				value=datavalue();
1119  				maker.put(matchGreaterThan); maker.put(value);
1120  			}
1121  			else if ((LA(1) == LE) && ((LA(2) >= HEXCONSTANT && LA(2) <= STRING))) {
1122  				match(LE);
1123  				string value;
1124  				value=datavalue();
1125  				maker.put(matchLessEqual); maker.put(value);
1126  			}
1127  			else if ((LA(1) == GE) && ((LA(2) >= HEXCONSTANT && LA(2) <= STRING))) {
1128  				match(GE);
1129  				string value;
1130  				value=datavalue();
1131  				maker.put(matchGreaterEqual); maker.put(value);
1132  			}
1133  			else if ((LA(1) == LESS) && (LA(2) == LITERAL_timestamp)) {
1134  				match(LESS);
1135  				int64_t value;
1136  				value=timestamp();
1137  				maker.put(matchBefore); maker.put(value);
1138  			}
1139  			else if ((LA(1) == GT) && (LA(2) == LITERAL_timestamp)) {
1140  				match(GT);
1141  				int64_t value;
1142  				value=timestamp();
1143  				maker.put(matchAfter); maker.put(value);
1144  			}
1145  			else if ((LA(1) == LE) && (LA(2) == LITERAL_timestamp)) {
1146  				match(LE);
1147  				int64_t value;
1148  				value=timestamp();
1149  				maker.put(matchOnOrBefore); maker.put(value);
1150  			}
1151  			else if ((LA(1) == GE) && (LA(2) == LITERAL_timestamp)) {
1152  				match(GE);
1153  				int64_t value;
1154  				value=timestamp();
1155  				maker.put(matchOnOrAfter); maker.put(value);
1156  			}
1157  		else {
1158  			throw antlr::NoViableAltException(LT(1), getFilename());
1159  		}
1160  		}
1161  	}
1162  	catch (antlr::RecognitionException& ex) {
1163  		reportError(ex);
1164  		recover(ex,_tokenSet_9);
1165  	}
1166  }
1167  
1168  string  RequirementParser::datavalue() {
1169  	string result;
1170  	antlr::RefToken  hex = antlr::nullToken;
1171  	
1172  	try {      // for error handling
1173  		switch ( LA(1)) {
1174  		case DOTKEY:
1175  		case STRING:
1176  		{
1177  			result=stringvalue();
1178  			break;
1179  		}
1180  		case HEXCONSTANT:
1181  		{
1182  			hex = LT(1);
1183  			match(HEXCONSTANT);
1184  			result = hexString(hex->getText());
1185  			break;
1186  		}
1187  		default:
1188  		{
1189  			throw antlr::NoViableAltException(LT(1), getFilename());
1190  		}
1191  		}
1192  	}
1193  	catch (antlr::RecognitionException& ex) {
1194  		reportError(ex);
1195  		recover(ex,_tokenSet_17);
1196  	}
1197  	return result;
1198  }
1199  
1200  int64_t  RequirementParser::timestamp() {
1201  	int64_t result;
1202  	antlr::RefToken  s = antlr::nullToken;
1203  	
1204  	try {      // for error handling
1205  		match(LITERAL_timestamp);
1206  		s = LT(1);
1207  		match(STRING);
1208  		result = (int64_t)SecAbsoluteTimeFromDateContent(ASN1_GENERALIZED_TIME, (uint8_t const *)s->getText().c_str(), s->getText().length());
1209  	}
1210  	catch (antlr::RecognitionException& ex) {
1211  		reportError(ex);
1212  		recover(ex,_tokenSet_9);
1213  	}
1214  	return result;
1215  }
1216  
1217  string  RequirementParser::stringvalue() {
1218  	string result;
1219  	antlr::RefToken  dk = antlr::nullToken;
1220  	antlr::RefToken  s = antlr::nullToken;
1221  	
1222  	try {      // for error handling
1223  		switch ( LA(1)) {
1224  		case DOTKEY:
1225  		{
1226  			dk = LT(1);
1227  			match(DOTKEY);
1228  			result = dk->getText();
1229  			break;
1230  		}
1231  		case STRING:
1232  		{
1233  			s = LT(1);
1234  			match(STRING);
1235  			result = s->getText();
1236  			break;
1237  		}
1238  		default:
1239  		{
1240  			throw antlr::NoViableAltException(LT(1), getFilename());
1241  		}
1242  		}
1243  	}
1244  	catch (antlr::RecognitionException& ex) {
1245  		reportError(ex);
1246  		recover(ex,_tokenSet_18);
1247  	}
1248  	return result;
1249  }
1250  
1251  string  RequirementParser::pathstring() {
1252  	string result;
1253  	antlr::RefToken  dk = antlr::nullToken;
1254  	antlr::RefToken  s = antlr::nullToken;
1255  	antlr::RefToken  pn = antlr::nullToken;
1256  	
1257  	try {      // for error handling
1258  		switch ( LA(1)) {
1259  		case DOTKEY:
1260  		{
1261  			dk = LT(1);
1262  			match(DOTKEY);
1263  			result = dk->getText();
1264  			break;
1265  		}
1266  		case STRING:
1267  		{
1268  			s = LT(1);
1269  			match(STRING);
1270  			result = s->getText();
1271  			break;
1272  		}
1273  		case PATHNAME:
1274  		{
1275  			pn = LT(1);
1276  			match(PATHNAME);
1277  			result = pn->getText();
1278  			break;
1279  		}
1280  		default:
1281  		{
1282  			throw antlr::NoViableAltException(LT(1), getFilename());
1283  		}
1284  		}
1285  	}
1286  	catch (antlr::RecognitionException& ex) {
1287  		reportError(ex);
1288  		recover(ex,_tokenSet_9);
1289  	}
1290  	return result;
1291  }
1292  
1293  void RequirementParser::initializeASTFactory( antlr::ASTFactory& )
1294  {
1295  }
1296  const char* RequirementParser::tokenNames[] = {
1297  	"<0>",
1298  	"EOF",
1299  	"<2>",
1300  	"NULL_TREE_LOOKAHEAD",
1301  	"ARROW",
1302  	"\"guest\"",
1303  	"\"host\"",
1304  	"\"designated\"",
1305  	"\"library\"",
1306  	"\"plugin\"",
1307  	"\"or\"",
1308  	"\"and\"",
1309  	"LPAREN",
1310  	"RPAREN",
1311  	"NOT",
1312  	"\"always\"",
1313  	"\"true\"",
1314  	"\"never\"",
1315  	"\"false\"",
1316  	"\"identifier\"",
1317  	"\"cdhash\"",
1318  	"\"platform\"",
1319  	"\"notarized\"",
1320  	"\"legacy\"",
1321  	"\"anchor\"",
1322  	"\"apple\"",
1323  	"\"generic\"",
1324  	"\"certificate\"",
1325  	"\"cert\"",
1326  	"\"trusted\"",
1327  	"\"info\"",
1328  	"\"entitlement\"",
1329  	"\"exists\"",
1330  	"\"absent\"",
1331  	"EQL",
1332  	"EQQL",
1333  	"STAR",
1334  	"SUBS",
1335  	"LESS",
1336  	"GT",
1337  	"LE",
1338  	"GE",
1339  	"LBRACK",
1340  	"RBRACK",
1341  	"NEG",
1342  	"\"leaf\"",
1343  	"\"root\"",
1344  	"HASHCONSTANT",
1345  	"HEXCONSTANT",
1346  	"DOTKEY",
1347  	"STRING",
1348  	"PATHNAME",
1349  	"INTEGER",
1350  	"\"timestamp\"",
1351  	"SEMI",
1352  	"IDENT",
1353  	"HEX",
1354  	"COMMA",
1355  	"WS",
1356  	"SHELLCOMMENT",
1357  	"C_COMMENT",
1358  	"CPP_COMMENT",
1359  	0
1360  };
1361  
1362  const unsigned long RequirementParser::_tokenSet_0_data_[] = { 2UL, 0UL, 0UL, 0UL };
1363  // EOF 
1364  const antlr::BitSet RequirementParser::_tokenSet_0(_tokenSet_0_data_,4);
1365  const unsigned long RequirementParser::_tokenSet_1_data_[] = { 992UL, 1048576UL, 0UL, 0UL };
1366  // "guest" "host" "designated" "library" "plugin" INTEGER 
1367  const antlr::BitSet RequirementParser::_tokenSet_1(_tokenSet_1_data_,4);
1368  const unsigned long RequirementParser::_tokenSet_2_data_[] = { 16UL, 0UL, 0UL, 0UL };
1369  // ARROW 
1370  const antlr::BitSet RequirementParser::_tokenSet_2(_tokenSet_2_data_,4);
1371  const unsigned long RequirementParser::_tokenSet_3_data_[] = { 994UL, 1048576UL, 0UL, 0UL };
1372  // EOF "guest" "host" "designated" "library" "plugin" INTEGER 
1373  const antlr::BitSet RequirementParser::_tokenSet_3(_tokenSet_3_data_,4);
1374  const unsigned long RequirementParser::_tokenSet_4_data_[] = { 536883186UL, 6194188UL, 0UL, 0UL };
1375  // EOF ARROW "guest" "host" "designated" "library" "plugin" "or" "and" 
1376  // RPAREN "trusted" EQL EQQL LBRACK HASHCONSTANT DOTKEY STRING PATHNAME 
1377  // INTEGER SEMI 
1378  const antlr::BitSet RequirementParser::_tokenSet_4(_tokenSet_4_data_,4);
1379  const unsigned long RequirementParser::_tokenSet_5_data_[] = { 9186UL, 5242880UL, 0UL, 0UL };
1380  // EOF "guest" "host" "designated" "library" "plugin" RPAREN INTEGER SEMI 
1381  const antlr::BitSet RequirementParser::_tokenSet_5(_tokenSet_5_data_,4);
1382  const unsigned long RequirementParser::_tokenSet_6_data_[] = { 994UL, 5242880UL, 0UL, 0UL };
1383  // EOF "guest" "host" "designated" "library" "plugin" INTEGER SEMI 
1384  const antlr::BitSet RequirementParser::_tokenSet_6(_tokenSet_6_data_,4);
1385  const unsigned long RequirementParser::_tokenSet_7_data_[] = { 10210UL, 5242880UL, 0UL, 0UL };
1386  // EOF "guest" "host" "designated" "library" "plugin" "or" RPAREN INTEGER 
1387  // SEMI 
1388  const antlr::BitSet RequirementParser::_tokenSet_7(_tokenSet_7_data_,4);
1389  const unsigned long RequirementParser::_tokenSet_8_data_[] = { 3657420800UL, 0UL, 0UL, 0UL };
1390  // LPAREN NOT "always" "true" "never" "false" "identifier" "cdhash" "platform" 
1391  // "notarized" "legacy" "anchor" "certificate" "cert" "info" "entitlement" 
1392  const antlr::BitSet RequirementParser::_tokenSet_8(_tokenSet_8_data_,4);
1393  const unsigned long RequirementParser::_tokenSet_9_data_[] = { 12258UL, 5242880UL, 0UL, 0UL };
1394  // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN 
1395  // INTEGER SEMI 
1396  const antlr::BitSet RequirementParser::_tokenSet_9(_tokenSet_9_data_,4);
1397  const unsigned long RequirementParser::_tokenSet_10_data_[] = { 0UL, 1077248UL, 0UL, 0UL };
1398  // NEG "leaf" "root" INTEGER 
1399  const antlr::BitSet RequirementParser::_tokenSet_10(_tokenSet_10_data_,4);
1400  const unsigned long RequirementParser::_tokenSet_11_data_[] = { 0UL, 951308UL, 0UL, 0UL };
1401  // EQL EQQL LBRACK HASHCONSTANT DOTKEY STRING PATHNAME 
1402  const antlr::BitSet RequirementParser::_tokenSet_11(_tokenSet_11_data_,4);
1403  const unsigned long RequirementParser::_tokenSet_12_data_[] = { 0UL, 1998848UL, 0UL, 0UL };
1404  // HASHCONSTANT DOTKEY STRING PATHNAME INTEGER 
1405  const antlr::BitSet RequirementParser::_tokenSet_12(_tokenSet_12_data_,4);
1406  const unsigned long RequirementParser::_tokenSet_13_data_[] = { 536870912UL, 951308UL, 0UL, 0UL };
1407  // "trusted" EQL EQQL LBRACK HASHCONSTANT DOTKEY STRING PATHNAME 
1408  const antlr::BitSet RequirementParser::_tokenSet_13(_tokenSet_13_data_,4);
1409  const unsigned long RequirementParser::_tokenSet_14_data_[] = { 12258UL, 6193153UL, 0UL, 0UL };
1410  // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN 
1411  // "exists" HASHCONSTANT DOTKEY STRING PATHNAME INTEGER SEMI 
1412  const antlr::BitSet RequirementParser::_tokenSet_14(_tokenSet_14_data_,4);
1413  const unsigned long RequirementParser::_tokenSet_15_data_[] = { 12258UL, 5243887UL, 0UL, 0UL };
1414  // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN 
1415  // "exists" "absent" EQL EQQL SUBS LESS GT LE GE INTEGER SEMI 
1416  const antlr::BitSet RequirementParser::_tokenSet_15(_tokenSet_15_data_,4);
1417  const unsigned long RequirementParser::_tokenSet_16_data_[] = { 0UL, 458768UL, 0UL, 0UL };
1418  // STAR HEXCONSTANT DOTKEY STRING 
1419  const antlr::BitSet RequirementParser::_tokenSet_16(_tokenSet_16_data_,4);
1420  const unsigned long RequirementParser::_tokenSet_17_data_[] = { 12258UL, 5242896UL, 0UL, 0UL };
1421  // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN 
1422  // STAR INTEGER SEMI 
1423  const antlr::BitSet RequirementParser::_tokenSet_17(_tokenSet_17_data_,4);
1424  const unsigned long RequirementParser::_tokenSet_18_data_[] = { 12258UL, 5244944UL, 0UL, 0UL };
1425  // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN 
1426  // STAR RBRACK INTEGER SEMI 
1427  const antlr::BitSet RequirementParser::_tokenSet_18(_tokenSet_18_data_,4);
1428  
1429  
1430  ANTLR_END_NAMESPACE