summaryrefslogtreecommitdiff
path: root/src/vm/securitymeta.h
blob: e64b97b0db71858374ff22fc0aa44c5f1a9a66f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
//--------------------------------------------------------------------------
// securitymeta.h
//
// pre-computes various security information, declarative and runtime meta-info
//


// 
//--------------------------------------------------------------------------


#ifndef __SECURITYMETA_H__
#define __SECURITYMETA_H__

class SecurityStackWalk;
class AssertStackWalk;
class PsetCacheEntry;
class SecurityTransparencyBehavior;
struct DeclActionInfo;

#define INVALID_SET_INDEX ((DWORD)~0)

// The enum that describes the value of the SecurityCriticalFlags in SecurityCritical attribute.
enum SecurityCriticalFlags
{
    SecurityCriticalFlags_None = 0,
    SecurityCriticalFlags_All = 0x1
};

// Security rule sets that can be used - this enum should match the BCL SecurityRuleSet enum
enum SecurityRuleSet
{
    SecurityRuleSet_Level1  = 1,        // v2.0 rules
    SecurityRuleSet_Level2  = 2,        // v4.0 rules

    SecurityRuleSet_Min     = SecurityRuleSet_Level1,   // Smallest rule set we understand
    SecurityRuleSet_Max     = SecurityRuleSet_Level2,   // Largest rule set we understand
    SecurityRuleSet_Default = SecurityRuleSet_Level2    // Rule set to use if unspecified
};

// Partial trust visibility level for APTCA assemblies - this enum should match the BCL
// PartialTrustVisibilityLevel enum
enum PartialTrustVisibilityLevel
{
    PartialTrustVisibilityLevel_VisibleToAllHosts = 0,
    PartialTrustVisibilityLevel_NotVisibleByDefault = 1
};

SELECTANY const DWORD DCL_FLAG_MAP[] =
{
    0,                                  // dclActionNil                 = 0
    DECLSEC_REQUESTS,                   // dclRequest                   = 1
    DECLSEC_DEMANDS,                    // dclDemand                    = 2
    DECLSEC_ASSERTIONS,                 // dclAssert                    = 3
    DECLSEC_DENIALS,                    // dclDeny                      = 4
    DECLSEC_PERMITONLY,                 // dclPermitOnly                = 5
    DECLSEC_LINK_CHECKS,                // dclLinktimeCheck             = 6
    DECLSEC_INHERIT_CHECKS,             // dclInheritanceCheck          = 7
    DECLSEC_REQUESTS,                   // dclRequestMinimum            = 8
    DECLSEC_REQUESTS,                   // dclRequestOptional           = 9
    DECLSEC_REQUESTS,                   // dclRequestRefuse             = 10
    0,                                  // dclPrejitGrant               = 11
    0,                                  // dclPrejitDenied              = 12
    DECLSEC_NONCAS_DEMANDS,             // dclNonCasDemand              = 13
    DECLSEC_NONCAS_LINK_DEMANDS,        // dclNonCasLinkDemand          = 14
    DECLSEC_NONCAS_INHERITANCE,         // dclNonCasInheritance         = 15
};
#define DCL_FLAG_MAP_SIZE (sizeof(DCL_FLAG_MAP)/sizeof(DWORD))
#define  DclToFlag(dcl) (((size_t)dcl < DCL_FLAG_MAP_SIZE) ? DCL_FLAG_MAP[dcl] : 0)


struct TokenDeclActionInfo
{
    DWORD           dwDeclAction;   // This'll tell InvokeDeclarativeSecurity whats the action needed
    PsetCacheEntry *pPCE;     // The cached permissionset on which to demand/assert/deny/etc
    TokenDeclActionInfo* pNext;        // pointer to next action link in chain
    
    static TokenDeclActionInfo *Init(DWORD dwAction, PsetCacheEntry *pPCE);
    static void LinkNewDeclAction(TokenDeclActionInfo** ppActionList, CorDeclSecurity action, PsetCacheEntry *pPCE);


    HRESULT GetDeclaredPermissionsWithCache(IN CorDeclSecurity action,
                                            OUT OBJECTREF *pDeclaredPermissions,
                                            OUT PsetCacheEntry **pPCE);

    OBJECTREF GetLinktimePermissions(OBJECTREF *prefNonCasDemands);
    void InvokeLinktimeChecks(Assembly* pCaller);
};

// Flags about the raw security attributes found on a metadata token, as well as semantic interpretations of
// them in some cases (see code:TokenSecurityDescriptor#TokenSecurityDescriptorSemanticLookup).  These flags
// are split into several sections:
//
// 32              28           16              12               4          0
// | Rules version | Rules Bits | Semantic data | Raw attributes | Metabits |
//
//   Rules version  - the SecurityRuleSet selected by a SecurityRules attribute
//   Rules bits     - extra flags set on a SecurityRules attribute
//   Semantic data  - Flags indicating the security state of the item represented by the token taking into
//                    account parent types and modules - giving the true semantic security state
//                    (see code:TokenSecurityDescriptor#TokenSecurityDescriptorSemanticLookup)
//   Raw attributes - Flags for data we read directly out of metadata; these only indicate that the attributes
//                    are set, and do not indicate the actual security state of the token until they have been
//                    interpreted by the assembly they are applied within.
//   Metabits       - Flags about the state of the token security descriptor itself
enum TokenSecurityDescriptorFlags
{
    // Metabits
    TokenSecurityDescriptorFlags_None                       = 0x00000000,
    TokenSecurityDescriptorFlags_IsComputed                 = 0x00000001,

    // Raw attributes
    TokenSecurityDescriptorFlags_RawAttributeMask           = 0x00000FF0,
    TokenSecurityDescriptorFlags_AllCritical                = 0x00000010,   // [SecurityCritical(SecurityCriticalScope.All)]
    TokenSecurityDescriptorFlags_APTCA                      = 0x00000020,   // [AllowPartiallyTrustedCallers] (VisibleByDefault)
    TokenSecurityDescriptorFlags_ConditionalAPTCA           = 0x00000040,   // [AllowPartiallyTrustedCallers] (NotVisibleByDefault)
    TokenSecurityDescriptorFlags_Critical                   = 0x00000080,   // [SecurityCritical] (regardless of scope)
    TokenSecurityDescriptorFlags_SecurityRules              = 0x00000100,   // [SecurityRules]
    TokenSecurityDescriptorFlags_SafeCritical               = 0x00000200,   // [SecuritySafeCritical]
    TokenSecurityDescriptorFlags_Transparent                = 0x00000400,   // [SecurityTransparent]
    TokenSecurityDescriptorFlags_TreatAsSafe                = 0x00000800,   // [SecurityTreatAsSafe]

    // Semantic data
    TokenSecurityDescriptorFlags_SemanticMask               = 0x000FF000,
    TokenSecurityDescriptorFlags_IsSemanticComputed         = 0x00001000,
    TokenSecurityDescriptorFlags_IsSemanticCritical         = 0x00002000,
    TokenSecurityDescriptorFlags_IsSemanticTreatAsSafe      = 0x00004000,
    TokenSecurityDescriptorFlags_IsSemanticExternallyVisible= 0x00008000,

    // Rules bits
    TokenSecurityDescriptorFlags_RulesMask                  = 0x0FFF0000,
    TokenSecurityDescriptorFlags_SkipFullTrustVerification  = 0x00010000,   // In full trust do not do IL verificaiton for transparent code

    // Rules version
    TokenSecurityDescriptorFlags_RulesVersionMask           = 0xF0000000
};

inline TokenSecurityDescriptorFlags operator|(TokenSecurityDescriptorFlags lhs,
                                              TokenSecurityDescriptorFlags rhs);

inline TokenSecurityDescriptorFlags operator|=(TokenSecurityDescriptorFlags& lhs,
                                               TokenSecurityDescriptorFlags rhs);

inline TokenSecurityDescriptorFlags operator&(TokenSecurityDescriptorFlags lhs,
                                              TokenSecurityDescriptorFlags rhs);

inline TokenSecurityDescriptorFlags operator&=(TokenSecurityDescriptorFlags& lhs,
                                               TokenSecurityDescriptorFlags rhs);

inline TokenSecurityDescriptorFlags operator~(TokenSecurityDescriptorFlags flags);

// Get the version of the security rules that token security descriptor flags are requesting
inline SecurityRuleSet GetSecurityRuleSet(TokenSecurityDescriptorFlags flags);

// Encode a security rule set into token flags - this reverses GetSecurityRuleSet
inline TokenSecurityDescriptorFlags EncodeSecurityRuleSet(SecurityRuleSet ruleSet);

#ifdef FEATURE_APTCA
TokenSecurityDescriptorFlags ParseAptcaAttribute(const BYTE *pbAptcaBlob,
                                                 DWORD cbAptcaBlob);
#endif // FEATURE_APTCA

TokenSecurityDescriptorFlags ParseSecurityRulesAttribute(const BYTE *pbSecurityRulesBlob,
                                                         DWORD cbSecurityRulesBlob);

//
// #TokenSecurityDescriptorSemanticLookup
// 
// Token security descriptors are used to get information on the security state of a specific metadata
// token. They have two types of lookup - standard and semantic. Standard lookup is cheaper and only looks at
// the specific metadata token.  Semantic lookup will follow the token to its parents, figuring out if the
// token is semanticaly critical or transparent due to a containing item.  For instance:
// 
//     [SecurityCritical]
//     class A
//     {
//         class B { }
//     }
// 
// A TokenSecurityDescriptor's standard lookup for B will say that it is transparent because B does not
// directly have a critical attribute.  However, a semantic lookup will notice that A is critical and
// contains B, therefore B is also critical.
//

class TokenSecurityDescriptor
{
private:
    PTR_Module                      m_pModule;
    mdToken                         m_token;
    TokenSecurityDescriptorFlags    m_flags;

public:
    inline TokenSecurityDescriptor(PTR_Module pModule, mdToken token);

    void VerifyDataComputed();
    void VerifySemanticDataComputed();

    // Get the raw flags for the token
    inline TokenSecurityDescriptorFlags GetFlags();

    //
    // Critical / transparent checks for the specific metadata token only - these methods do not take into
    // account the containment of the token and therefore only include information about the token itself
    // and cannot be used to determine if the item represented by the token is semantically critical.
    // 
    // See code:TokenSecurityDescriptor#TokenSecurityDescriptorSemanticLookup
    //
    
    // Get the attributes that were set on the token
    inline TokenSecurityDescriptorFlags GetMetadataFlags();

    //
    // Semantic critical / transparent checks for the metadata token - these methods take into account
    // containers of the token to get a true semantic security status for the token.
    // 
    // See code:TokenSecurityDescriptor#TokenSecurityDescriptorSemanticLookup
    //

    inline BOOL IsSemanticCritical();

    inline BOOL IsSemanticTreatAsSafe();
    
    inline BOOL IsSemanticExternallyVisible();

    // static helper to find cached security descriptors based on token
    static HashDatum LookupSecurityDescriptor(void* pKey);

    static HashDatum LookupSecurityDescriptor_Slow(AppDomain* pDomain,
                                                   void* pKey,   
                                                   EEPtrHashTable  &rCachedMethodPermissionsHash );

    // static helper to insert a security descriptor for a token, dupes not allowed, returns previous entry in hash table
    static HashDatum InsertSecurityDescriptor(void* pKey, HashDatum pHashDatum);

    // static helper to parse the security attributes for a token from a given metadata importer
    static TokenSecurityDescriptorFlags ReadSecurityAttributes(IMDInternalImport *pmdImport, mdToken token);

private:
    // does the type represented by this TokenSecurityDescriptor particpate in type equivalence
    inline BOOL IsTypeEquivalent();

private:
    // Helper class which fires transparency calculation begin/end ETW events
    class TokenSecurityDescriptorTransparencyEtwEvents
    {
    private:
        const TokenSecurityDescriptor *m_pTSD;

    public:
        inline TokenSecurityDescriptorTransparencyEtwEvents(const TokenSecurityDescriptor *pTSD);
        inline ~TokenSecurityDescriptorTransparencyEtwEvents();
    };
};

enum MethodSecurityDescriptorFlags
{
    MethodSecurityDescriptorFlags_None                  = 0x0000,
    MethodSecurityDescriptorFlags_IsComputed            = 0x0001,

    // Method transparency info is cached directly on MethodDesc for performance reasons
    // These flags are used only during calculation of transparency information; runtime data
    // should be read from the method desc
    MethodSecurityDescriptorFlags_IsCritical            = 0x0002,
    MethodSecurityDescriptorFlags_IsTreatAsSafe         = 0x0004,

    MethodSecurityDescriptorFlags_IsBuiltInCASPermsOnly = 0x0008,
    MethodSecurityDescriptorFlags_IsDemandsOnly         = 0x0010,
    MethodSecurityDescriptorFlags_AssertAllowed         = 0x0020,
    MethodSecurityDescriptorFlags_CanCache              = 0x0040,
};

inline MethodSecurityDescriptorFlags operator|(MethodSecurityDescriptorFlags lhs,
                                               MethodSecurityDescriptorFlags rhs);

inline MethodSecurityDescriptorFlags operator|=(MethodSecurityDescriptorFlags& lhs,
                                                MethodSecurityDescriptorFlags rhs);

inline MethodSecurityDescriptorFlags operator&(MethodSecurityDescriptorFlags lhs,
                                               MethodSecurityDescriptorFlags rhs);

inline MethodSecurityDescriptorFlags operator&=(MethodSecurityDescriptorFlags& lhs,
                                                MethodSecurityDescriptorFlags rhs);

class MethodSecurityDescriptor 
{
private:
    MethodDesc                      *m_pMD;
    DeclActionInfo                  *m_pRuntimeDeclActionInfo;  // run-time declarative actions list    
    TokenDeclActionInfo             *m_pTokenDeclActionInfo;    // link-time declarative actions list
    MethodSecurityDescriptorFlags   m_flags;
    DWORD                            m_declFlagsDuringPreStub;   // declarative run-time security flags,    

public:
    explicit inline MethodSecurityDescriptor(MethodDesc* pMD, BOOL fCanCache = TRUE);

    inline BOOL CanAssert();
    inline void SetCanAssert();

    inline BOOL CanCache();
    inline void SetCanCache();
    
    inline BOOL HasRuntimeDeclarativeSecurity();
    inline BOOL HasLinkOrInheritanceDeclarativeSecurity();
    inline BOOL HasLinktimeDeclarativeSecurity();
    inline BOOL HasInheritanceDeclarativeSecurity();

    inline mdToken GetToken();
    inline MethodDesc *GetMethod();
    inline IMDInternalImport *GetIMDInternalImport();

    inline BOOL ContainsBuiltInCASDemandsOnly();
    inline DeclActionInfo* GetRuntimeDeclActionInfo();
    inline DWORD GetDeclFlagsDuringPreStub();
    inline TokenDeclActionInfo* GetTokenDeclActionInfo();

    inline BOOL IsCritical();
    inline BOOL IsTreatAsSafe();

    inline BOOL IsOpportunisticallyCritical();

    inline HRESULT GetDeclaredPermissionsWithCache(IN CorDeclSecurity action,
                                                   OUT OBJECTREF *pDeclaredPermissions,
                                                   OUT PsetCacheEntry **pPCE);

    static HRESULT GetDeclaredPermissionsWithCache(MethodDesc* pMD,
                                                   IN CorDeclSecurity action,
                                                   OUT OBJECTREF *pDeclaredPermissions,
                                                   OUT PsetCacheEntry **pPCE);
    
    static OBJECTREF GetLinktimePermissions(MethodDesc* pMD, OBJECTREF *prefNonCasDemands);

    inline void InvokeLinktimeChecks(Assembly* pCaller);
    static inline void InvokeLinktimeChecks(MethodDesc* pMD, Assembly* pCaller);

    void InvokeInheritanceChecks(MethodDesc *pMethod);

    // This method will look for the cached copy of the MethodSecurityDescriptor corresponding to ret_methSecDesc->_pMD
    // If the cache lookup succeeds, we get back the cached copy in ret_methSecDesc
    // If the cache lookup fails, then the data is computed in ret_methSecDesc. If we find that this is a cache-able MSD,
    // a copy is made in AppDomain heap and inserted into the hash table for future lookups.
    static void LookupOrCreateMethodSecurityDescriptor(MethodSecurityDescriptor* ret_methSecDesc);
    static BOOL IsDeclSecurityCASDemandsOnly(DWORD dwMethDeclFlags,
                                             mdToken _mdToken,
                                             IMDInternalImport *pInternalImport);

private:
    void ComputeRuntimeDeclarativeSecurityInfo();
    void ComputeMethodDeclarativeSecurityInfo();

    inline void VerifyDataComputed();
    void VerifyDataComputedInternal();
    
    // Force the type to figure out if it is transparent or critial.
    // NOTE: Generally this is not needed, as the data is cached on the MethodDesc for you. This method should
    // only be called if the MethodDesc is returning FALSE from HasCriticalTransparentInfo
    void ComputeCriticalTransparentInfo();

    static BOOL CanMethodSecurityDescriptorBeCached(MethodDesc* pMD);

private:
    // Helper class which fires transparency calculation begin/end ETW events
    class MethodSecurityDescriptorTransparencyEtwEvents
    {
    private:
        const MethodSecurityDescriptor *m_pMSD;

    public:
        inline MethodSecurityDescriptorTransparencyEtwEvents(const MethodSecurityDescriptor *pMSD);
        inline ~MethodSecurityDescriptorTransparencyEtwEvents();
    };

    // Helper class to iterater over methods that the MethodSecurityDescriptor's MethodDesc may be
    // implementing.  This type iterates over interface implementations followed by MethodImpls for virtuals
    // that the input MethodDesc implements.
    class MethodImplementationIterator
    {
    private:
        DispatchMap::Iterator m_interfaceIterator;
        MethodDesc *m_pMD;
        DWORD m_iMethodImplIndex;
        bool m_fInterfaceIterationBegun;
        bool m_fMethodImplIterationBegun;

    public:
        MethodImplementationIterator(MethodDesc *pMD);

        MethodDesc *Current();
        bool IsValid();
        void Next();
    };
};
            
enum FieldSecurityDescriptorFlags
{
    FieldSecurityDescriptorFlags_None                   = 0x0000,
    FieldSecurityDescriptorFlags_IsComputed             = 0x0001,
    FieldSecurityDescriptorFlags_IsCritical             = 0x0002,
    FieldSecurityDescriptorFlags_IsTreatAsSafe          = 0x0004,
};

inline FieldSecurityDescriptorFlags operator|(FieldSecurityDescriptorFlags lhs,
                                              FieldSecurityDescriptorFlags rhs);

inline FieldSecurityDescriptorFlags operator|=(FieldSecurityDescriptorFlags& lhs,
                                               FieldSecurityDescriptorFlags rhs);

inline FieldSecurityDescriptorFlags operator&(FieldSecurityDescriptorFlags lhs,
                                              FieldSecurityDescriptorFlags rhs);

inline FieldSecurityDescriptorFlags operator&=(FieldSecurityDescriptorFlags& lhs,
                                               FieldSecurityDescriptorFlags rhs);

class FieldSecurityDescriptor
{
private:
    FieldDesc                       *m_pFD;
    FieldSecurityDescriptorFlags    m_flags;

public:
    explicit inline FieldSecurityDescriptor(FieldDesc* pFD);

    void VerifyDataComputed();

    inline BOOL IsCritical();
    inline BOOL IsTreatAsSafe();

private:
    // Helper class which fires transparency calculation begin/end ETW events
    class FieldSecurityDescriptorTransparencyEtwEvents
    {
    private:
        const FieldSecurityDescriptor *m_pFSD;

    public:
        inline FieldSecurityDescriptorTransparencyEtwEvents(const FieldSecurityDescriptor *pFSD);
        inline ~FieldSecurityDescriptorTransparencyEtwEvents();
    };
};

enum TypeSecurityDescriptorFlags
{
    TypeSecurityDescriptorFlags_None                = 0x0000,

    // Type transparency info is cached directly on EEClass for performance reasons; these bits are used only
    // as intermediate state while calculating the final set of bits to cache on  the EEClass
    TypeSecurityDescriptorFlags_IsAllCritical       = 0x0001,   // Everything introduced by this type is critical
    TypeSecurityDescriptorFlags_IsAllTransparent    = 0x0002,   // All code in the type is transparent
    TypeSecurityDescriptorFlags_IsCritical          = 0x0004,   // The type is critical, but its introduced methods may not be
    TypeSecurityDescriptorFlags_IsTreatAsSafe       = 0x0008,   // Combined with IsAllCritical or IsCritical makes the type SafeCritical
};

inline TypeSecurityDescriptorFlags operator|(TypeSecurityDescriptorFlags lhs,
                                             TypeSecurityDescriptorFlags rhs);

inline TypeSecurityDescriptorFlags operator|=(TypeSecurityDescriptorFlags& lhs,
                                              TypeSecurityDescriptorFlags rhs);

inline TypeSecurityDescriptorFlags operator&(TypeSecurityDescriptorFlags lhs,
                                             TypeSecurityDescriptorFlags rhs);

inline TypeSecurityDescriptorFlags operator&=(TypeSecurityDescriptorFlags& lhs,
                                              TypeSecurityDescriptorFlags rhs);

class TypeSecurityDescriptor
{
private:
    MethodTable                 *m_pMT;
    TokenDeclActionInfo         *m_pTokenDeclActionInfo;
    BOOL                        m_fIsComputed;

public:
    explicit inline TypeSecurityDescriptor(MethodTable *pMT);

    inline BOOL HasLinkOrInheritanceDeclarativeSecurity();       
    inline BOOL HasLinktimeDeclarativeSecurity();
    inline BOOL HasInheritanceDeclarativeSecurity();

    // Is everything introduced by the type critical
    inline BOOL IsAllCritical();

    // Does the type contain only transparent code
    inline BOOL IsAllTransparent();

    // Combined with IsCritical/IsAllCritical is the type safe critical
    inline BOOL IsTreatAsSafe();

    // Is the type critical, but not necessarially its conatined methods
    inline BOOL IsCritical();

    // Is the type in an assembly that doesn't care about transparency, and therefore wants the CLR to make
    // sure that all annotations are correct for it.
    inline BOOL IsOpportunisticallyCritical();

    // Should this type be considered externally visible when calculating the transpraency of the type
    // and its members. (For instance, when seeing if public implies treat as safe)
    BOOL IsTypeExternallyVisibleForTransparency();

    inline mdToken GetToken();
    inline IMDInternalImport *GetIMDInternalImport();

    inline TokenDeclActionInfo* GetTokenDeclActionInfo();

    inline HRESULT GetDeclaredPermissionsWithCache(IN CorDeclSecurity action,
                                                   OUT OBJECTREF *pDeclaredPermissions,
                                                   OUT PsetCacheEntry **pPCE);

    static HRESULT GetDeclaredPermissionsWithCache(MethodTable* pTargetMT,
                                                   IN CorDeclSecurity action,
                                                   OUT OBJECTREF *pDeclaredPermissions,
                                                   OUT PsetCacheEntry **pPCE);

    static OBJECTREF GetLinktimePermissions(MethodTable* pMT, OBJECTREF *prefNonCasDemands);

    // Is the type represented by this TypeSecurityDescripter participating in type equivalence
    inline BOOL IsTypeEquivalent();

    void InvokeInheritanceChecks(MethodTable* pMT);
    inline void InvokeLinktimeChecks(Assembly* pCaller);
    static inline void InvokeLinktimeChecks(MethodTable* pMT, Assembly* pCaller);

private:
    inline TypeSecurityDescriptor& operator=(const TypeSecurityDescriptor &tsd);
    void ComputeTypeDeclarativeSecurityInfo();
    static TypeSecurityDescriptor* GetTypeSecurityDescriptor(MethodTable* pMT);    
    void VerifyDataComputedInternal();
    inline void VerifyDataComputed();
    // Force the type to figure out if it is transparent or critial.
    // NOTE: Generally this is not needed, as the data is cached on the EEClass for you. This method should
    // only be called if the EEClass is returning FALSE from HasCriticalTransparentInfo
    void ComputeCriticalTransparentInfo();
    static BOOL CanTypeSecurityDescriptorBeCached(MethodTable* pMT);

private:
    // Helper class which fires transparency calculation begin/end ETW events
    class TypeSecurityDescriptorTransparencyEtwEvents
    {
    private:
        const TypeSecurityDescriptor *m_pTSD;

    public:
        inline TypeSecurityDescriptorTransparencyEtwEvents(const TypeSecurityDescriptor *pTSD);
        inline ~TypeSecurityDescriptorTransparencyEtwEvents();
    };
};


enum ModuleSecurityDescriptorFlags
{
    ModuleSecurityDescriptorFlags_None                          = 0x0000,
    ModuleSecurityDescriptorFlags_IsComputed                    = 0x0001,

    ModuleSecurityDescriptorFlags_IsAPTCA                       = 0x0002,       // The assembly allows partially trusted callers
    ModuleSecurityDescriptorFlags_IsAllCritical                 = 0x0004,       // Every type and method introduced by the assembly is critical
    ModuleSecurityDescriptorFlags_IsAllTransparent              = 0x0008,       // Every type and method in the assembly is transparent
    ModuleSecurityDescriptorFlags_IsTreatAsSafe                 = 0x0010,       // Combined with IsAllCritical - every type and method introduced by the assembly is safe critical
    ModuleSecurityDescriptorFlags_IsOpportunisticallyCritical   = 0x0020,       // Ensure that the assembly follows all transparency rules by making all methods critical or safe critical as needed
    ModuleSecurityDescriptorFlags_SkipFullTrustVerification     = 0x0040,       // Fully trusted transparent code does not require verification
    ModuleSecurityDescriptorFlags_TransparentDueToPartialTrust  = 0x0080,       // Whether we made the assembly all transparent because it was partially-trusted
    ModuleSecurityDescriptorFlags_IsMicrosoftPlatform           = 0x0100,       // Whether we made the assembly microsoft platform. Stored in ngen image to determine if the ngen 
                                                                                // was generated as microsoft platform assembly (full trust) or not.
};

inline ModuleSecurityDescriptorFlags operator|(ModuleSecurityDescriptorFlags lhs,
                                               ModuleSecurityDescriptorFlags rhs);

inline ModuleSecurityDescriptorFlags operator|=(ModuleSecurityDescriptorFlags& lhs,
                                                ModuleSecurityDescriptorFlags rhs);

inline ModuleSecurityDescriptorFlags operator&(ModuleSecurityDescriptorFlags lhs,
                                               ModuleSecurityDescriptorFlags rhs);

inline ModuleSecurityDescriptorFlags operator&=(ModuleSecurityDescriptorFlags& lhs,
                                                ModuleSecurityDescriptorFlags rhs);

inline ModuleSecurityDescriptorFlags operator~(ModuleSecurityDescriptorFlags flags);

#ifdef FEATURE_APTCA
BOOL CheckAssemblyHasBeenKillBitted(LPASSEMBLYNAME pAssemblyName, ULARGE_INTEGER uliFileVersion);
#endif

// Module security descriptor, this class contains static security information about the module
// this information will get persisted in the NGen image
class ModuleSecurityDescriptor
{
    friend class Module;

private:
    PTR_Module                    m_pModule;
    ModuleSecurityDescriptorFlags m_flags;
    TokenSecurityDescriptorFlags  m_tokenFlags;

private:
    explicit inline ModuleSecurityDescriptor(PTR_Module pModule);

public:
    static inline BOOL IsMarkedTransparent(Assembly* pAssembly);

    static ModuleSecurityDescriptor* GetModuleSecurityDescriptor(Assembly* pAssembly);

    void Save(DataImage *image);
    void Fixup(DataImage *image);

    void VerifyDataComputed();

    inline void OverrideTokenFlags(TokenSecurityDescriptorFlags tokenFlags);
    inline TokenSecurityDescriptorFlags GetTokenFlags();

    inline Module *GetModule();

#ifdef DACCESS_COMPILE
    // Get the value of the module security descriptor flags without forcing them to be computed
    inline ModuleSecurityDescriptorFlags GetRawFlags();
#endif // DACCESS_COMPILE

    // Is Microsoft Platform
    inline BOOL IsMicrosoftPlatform();

    // Is every method and type in the assembly transparent
    inline BOOL IsAllTransparent();

    // Is every method and type introduced by the assembly critical
    inline BOOL IsAllCritical();

    // Combined with IsAllCritical - is every method and type introduced by the assembly safe critical
    inline BOOL IsTreatAsSafe();

    // Does the assembly not care about transparency, and wants the CLR to take care of making sure everything
    // is annotated properly in the assembly.
    inline BOOL IsOpportunisticallyCritical();

    // Does the assembly contain a mix of critical and transparent code
    inline BOOL IsMixedTransparency();

    // Partial trust assemblies are forced all-transparent under some conditions. This 
    // tells us whether that is true for this particular assembly.
    inline BOOL IsAllTransparentDueToPartialTrust();

    // Get the rule set the assembly uses
    inline SecurityRuleSet GetSecurityRuleSet();

#ifndef FEATURE_CORECLR
    // Can fully trusted transparent code bypass verification
    inline BOOL CanTransparentCodeSkipVerification();
#endif // !FEATURE_CORECLR

#if defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
    // Does the assembly allow partially trusted callers
    inline BOOL IsAPTCA();
#endif // defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)

#ifndef FEATURE_CORECLR
    BOOL AssemblyVersionRequiresLegacyTransparency();
#endif // !FEATURE_CORECLR

private:
    // Helper class which fires transparency calculation begin/end ETW events
    class ModuleSecurityDescriptorTransparencyEtwEvents
    {
    private:
        ModuleSecurityDescriptor *m_pMSD;

    public:
        inline ModuleSecurityDescriptorTransparencyEtwEvents(ModuleSecurityDescriptor *pMSD);
        inline ~ModuleSecurityDescriptorTransparencyEtwEvents();
    };
};

#include "securitymeta.inl"

#endif // __SECURITYMETA_H__