File: system\security\accesscontrol\cryptokeysecurity.cs
Project: ndp\clr\src\bcl\mscorlib.csproj (mscorlib)
// ==++==
// 
//  Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// ==--==
 
//
// CryptoKeySecurity.cs
//
 
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Security.Principal;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
 
namespace System.Security.AccessControl {
    [Flags]
    public enum CryptoKeyRights {
        ReadData                     = 0x00000001,
        WriteData                    = 0x00000002,
        ReadExtendedAttributes       = 0x00000008,
        WriteExtendedAttributes      = 0x00000010,
        ReadAttributes               = 0x00000080,
        WriteAttributes              = 0x00000100,
        Delete                       = 0x00010000,
        ReadPermissions              = 0x00020000,
        ChangePermissions            = 0x00040000,
        TakeOwnership                = 0x00080000,
        Synchronize                  = 0x00100000,
        FullControl                  = 0x001F019B,
        GenericAll                   = 0x10000000,
        GenericExecute               = 0x20000000,
        GenericWrite                 = 0x40000000,
        GenericRead                  = unchecked((int) 0x80000000)
    }
 
    public sealed class CryptoKeyAccessRule : AccessRule {
        public CryptoKeyAccessRule (IdentityReference identity, CryptoKeyRights cryptoKeyRights, AccessControlType type)
                    : this (identity,
                            AccessMaskFromRights(cryptoKeyRights, type),
                            false,
                            InheritanceFlags.None,
                            PropagationFlags.None,
                            type) {
        }
 
        public CryptoKeyAccessRule (string identity, CryptoKeyRights cryptoKeyRights, AccessControlType type)
                    : this (new NTAccount(identity),
                            AccessMaskFromRights(cryptoKeyRights, type),
                            false,
                            InheritanceFlags.None,
                            PropagationFlags.None,
                            type) {
        }
 
        private CryptoKeyAccessRule (IdentityReference identity, int accessMask, bool isInherited,
                                     InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)
                    : base (identity,
                            accessMask,
                            isInherited,
                            inheritanceFlags,
                            propagationFlags,
                            type) {
        }
 
        public CryptoKeyRights CryptoKeyRights {
            get { return RightsFromAccessMask(base.AccessMask); }
        }
 
        // Acl's on files have a Synchronize bit, and CreateFile always
        // asks for it. So for allows, let's always include this bit,
        // and for denies, let's never include this bit unless we're denying
        // full control. This is the right thing for users, even if it does
        // make the model look asymmetrical from a purist point of view.
        // Also, crypto key containers are just files in the end, so
        // this tweak to the access rights for files makes sense here.
        private static int AccessMaskFromRights (CryptoKeyRights cryptoKeyRights, AccessControlType controlType) {
            if (controlType == AccessControlType.Allow) {
                cryptoKeyRights |= CryptoKeyRights.Synchronize;
            }
            else if (controlType == AccessControlType.Deny) {
                if (cryptoKeyRights != CryptoKeyRights.FullControl)
                    cryptoKeyRights &= ~CryptoKeyRights.Synchronize;
            }
            else {
                throw new ArgumentException(Environment.GetResourceString("Argument_InvalidEnumValue", controlType, "controlType"), "controlType");
            }
 
            return (int) cryptoKeyRights;
        }
 
        internal static CryptoKeyRights RightsFromAccessMask(int accessMask) {
            return (CryptoKeyRights) accessMask;
        }
    }
 
 
    public sealed class CryptoKeyAuditRule : AuditRule {
        public CryptoKeyAuditRule (IdentityReference identity, CryptoKeyRights cryptoKeyRights, AuditFlags flags)
                    : this (identity,
                            AccessMaskFromRights(cryptoKeyRights),
                            false,
                            InheritanceFlags.None,
                            PropagationFlags.None,
                            flags) {
        }
 
        public CryptoKeyAuditRule (string identity, CryptoKeyRights cryptoKeyRights, AuditFlags flags)
                    : this (new NTAccount(identity),
                            AccessMaskFromRights(cryptoKeyRights),
                            false,
                            InheritanceFlags.None,
                            PropagationFlags.None,
                            flags) {
        }
 
        private CryptoKeyAuditRule (IdentityReference identity, int accessMask, bool isInherited,
                                    InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags)
                    : base (identity,
                            accessMask,
                            isInherited,
                            inheritanceFlags,
                            propagationFlags,
                            flags) {
        }
 
        public CryptoKeyRights CryptoKeyRights {
            get { return RightsFromAccessMask(base.AccessMask); }
        }
 
        private static int AccessMaskFromRights (CryptoKeyRights cryptoKeyRights) {
            return (int) cryptoKeyRights;
        }
 
        internal static CryptoKeyRights RightsFromAccessMask(int accessMask) {
            return (CryptoKeyRights) accessMask;
        }
    }
 
 
    public sealed class CryptoKeySecurity : NativeObjectSecurity {
        private const ResourceType s_ResourceType = ResourceType.FileObject;
 
        public CryptoKeySecurity () : base(false, s_ResourceType) {}
        [System.Security.SecuritySafeCritical]  // auto-generated
        public CryptoKeySecurity (CommonSecurityDescriptor securityDescriptor) : base(s_ResourceType, securityDescriptor) {}
 
        public sealed override AccessRule AccessRuleFactory (IdentityReference identityReference,
                                                                int accessMask,
                                                                bool isInherited,
                                                                InheritanceFlags inheritanceFlags,
                                                                PropagationFlags propagationFlags,
                                                                AccessControlType type) {
            return new CryptoKeyAccessRule(
                identityReference,
                CryptoKeyAccessRule.RightsFromAccessMask(accessMask),
                type);
        }
 
        public sealed override AuditRule AuditRuleFactory (IdentityReference identityReference,
                                                              int accessMask,
                                                              bool isInherited,
                                                              InheritanceFlags inheritanceFlags,
                                                              PropagationFlags propagationFlags,
                                                              AuditFlags flags) {
            return new CryptoKeyAuditRule(
                identityReference,
                CryptoKeyAuditRule.RightsFromAccessMask(accessMask),
                flags);
        }
 
        public void AddAccessRule (CryptoKeyAccessRule rule) {
            base.AddAccessRule(rule);
        }
 
        public void SetAccessRule (CryptoKeyAccessRule rule) {
            base.SetAccessRule(rule);
        }
 
        public void ResetAccessRule (CryptoKeyAccessRule rule) {
            base.ResetAccessRule(rule);
        }
 
        public bool RemoveAccessRule (CryptoKeyAccessRule rule) {
            return base.RemoveAccessRule(rule);
        }
 
        public void RemoveAccessRuleAll (CryptoKeyAccessRule rule) {
            base.RemoveAccessRuleAll(rule);
        }
 
        public void RemoveAccessRuleSpecific (CryptoKeyAccessRule rule) {
            base.RemoveAccessRuleSpecific(rule);
        }
 
        public void AddAuditRule (CryptoKeyAuditRule rule) {
            base.AddAuditRule(rule);
        }
 
        public void SetAuditRule (CryptoKeyAuditRule rule) {
            base.SetAuditRule(rule);
        }
 
        public bool RemoveAuditRule (CryptoKeyAuditRule rule) {
            return base.RemoveAuditRule(rule);
        }
 
        public void RemoveAuditRuleAll (CryptoKeyAuditRule rule) {
            base.RemoveAuditRuleAll(rule);
        }
 
        public void RemoveAuditRuleSpecific (CryptoKeyAuditRule rule) {
            base.RemoveAuditRuleSpecific(rule);
        }
        
        #region some overrides
        public override Type AccessRightType
        {
            get { return typeof(System.Security.AccessControl.CryptoKeyRights); }
        }
        
        public override Type AccessRuleType
        {
            get { return typeof(System.Security.AccessControl.CryptoKeyAccessRule); }
        }
        
        public override Type AuditRuleType
        {
            get { return typeof(System.Security.AccessControl.CryptoKeyAuditRule); }
        }
        #endregion
 
        internal AccessControlSections ChangedAccessControlSections {
            [System.Security.SecurityCritical]  // auto-generated
            get {
                AccessControlSections changedSections = AccessControlSections.None;
 
                bool readLockAcquired = false;
 
                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try { }
                    finally {
                        ReadLock();
                        readLockAcquired = true;
                    }
 
                    if (AccessRulesModified)
                        changedSections |= AccessControlSections.Access;
                    if (AuditRulesModified)
                        changedSections |= AccessControlSections.Audit;
                    if (GroupModified)
                        changedSections |= AccessControlSections.Group;
                    if (OwnerModified)
                        changedSections |= AccessControlSections.Owner;
                }
                finally {
                    if (readLockAcquired) {
                        ReadUnlock();
                    }
                }
 
                return changedSections;
            }
        }
    }
}