internal static void SetAccessRuleOnKSPKey(CngKey key, string accountName, CryptoKeyRights keyAccessMask) { const string NCRYPT_SECURITY_DESCR_PROPERTY = "Security Descr"; const CngPropertyOptions DACL_SECURITY_INFORMATION = (CngPropertyOptions)4; // retrieve existing permissions var existingACL = key.GetProperty(NCRYPT_SECURITY_DESCR_PROPERTY, DACL_SECURITY_INFORMATION); // add new rule CryptoKeySecurity keySec = new CryptoKeySecurity(); keySec.SetSecurityDescriptorBinaryForm(existingACL.GetValue()); keySec.AddAccessRule(new CryptoKeyAccessRule(accountName, keyAccessMask, AccessControlType.Allow)); // put back CngProperty updatedACL = new CngProperty(existingACL.Name, keySec.GetSecurityDescriptorBinaryForm(), CngPropertyOptions.Persist | DACL_SECURITY_INFORMATION); key.SetProperty(updatedACL); }
/// <summary> /// Import a key from a file for use on the machine. /// </summary> /// <param name="providerName"></param> /// <param name="filePath"></param> public bool ImportKeyToKSP(string providerName, string keyName, string filePath, bool makeExportable = false) { CngProvider provider = new CngProvider(providerName); bool keyExists = doesKeyExists(provider, keyName); if (keyExists) { //Key already exists. Can't create it. return(false); } CryptoKeySecurity sec = new CryptoKeySecurity(); CngKeyCreationParameters keyParams = null; byte[] keyBlob = File.ReadAllBytes(filePath); CngProperty keyBlobProp = new CngProperty(new CngKeyBlobFormat("RSAFULLPRIVATEBLOB").Format, keyBlob, CngPropertyOptions.None); if (IsMicrosoftSoftwareKSP(provider)) { sec.AddAccessRule( new CryptoKeyAccessRule( new SecurityIdentifier(sidType: WellKnownSidType.BuiltinAdministratorsSid, domainSid: null), cryptoKeyRights: CryptoKeyRights.FullControl, type: AccessControlType.Allow)); sec.AddAccessRule( new CryptoKeyAccessRule( new SecurityIdentifier(sidType: WellKnownSidType.BuiltinSystemOperatorsSid, domainSid: null), cryptoKeyRights: CryptoKeyRights.GenericRead, type: AccessControlType.Allow)); const string NCRYPT_SECURITY_DESCR_PROPERTY = "Security Descr"; const CngPropertyOptions DACL_SECURITY_INFORMATION = (CngPropertyOptions)4; CngProperty permissions = new CngProperty( NCRYPT_SECURITY_DESCR_PROPERTY, sec.GetSecurityDescriptorBinaryForm(), CngPropertyOptions.Persist | DACL_SECURITY_INFORMATION); keyParams = new CngKeyCreationParameters() { ExportPolicy = makeExportable ? CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport : CngExportPolicies.None, Provider = provider, Parameters = { permissions, keyBlobProp }, KeyCreationOptions = CngKeyCreationOptions.MachineKey }; using (CngKey key = CngKey.Create(CngAlgorithm.Rsa, keyName, keyParams)) { if (key == null) { return(false); } return(true); } } else { keyParams = new CngKeyCreationParameters() { ExportPolicy = makeExportable ? CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport : CngExportPolicies.None, Provider = provider, Parameters = { keyBlobProp }, KeyCreationOptions = CngKeyCreationOptions.MachineKey }; using (CngKey key = CngKey.Create(CngAlgorithm.Rsa, keyName, keyParams)) { if (key == null) { return(false); } // nothing to do inside here, except to return without throwing an exception return(true); } } }
internal static void SetKeySetSecurityInfo(SafeProvHandle hProv, CryptoKeySecurity cryptoKeySecurity, AccessControlSections accessControlSections) { SecurityInfos securityInfo = (SecurityInfos)0; Privilege privilege = (Privilege)null; if ((accessControlSections & AccessControlSections.Owner) != AccessControlSections.None && cryptoKeySecurity._securityDescriptor.Owner != (SecurityIdentifier)null) { securityInfo |= SecurityInfos.Owner; } if ((accessControlSections & AccessControlSections.Group) != AccessControlSections.None && cryptoKeySecurity._securityDescriptor.Group != (SecurityIdentifier)null) { securityInfo |= SecurityInfos.Group; } if ((accessControlSections & AccessControlSections.Audit) != AccessControlSections.None) { securityInfo |= SecurityInfos.SystemAcl; } if ((accessControlSections & AccessControlSections.Access) != AccessControlSections.None && cryptoKeySecurity._securityDescriptor.IsDiscretionaryAclPresent) { securityInfo |= SecurityInfos.DiscretionaryAcl; } if (securityInfo == (SecurityInfos)0) { return; } int hr = 0; RuntimeHelpers.PrepareConstrainedRegions(); try { if ((securityInfo & SecurityInfos.SystemAcl) != (SecurityInfos)0) { privilege = new Privilege("SeSecurityPrivilege"); privilege.Enable(); } byte[] descriptorBinaryForm = cryptoKeySecurity.GetSecurityDescriptorBinaryForm(); if (descriptorBinaryForm != null) { if (descriptorBinaryForm.Length != 0) { hr = Utils.SetKeySetSecurityInfo(hProv, securityInfo, descriptorBinaryForm); } } } finally { if (privilege != null) { privilege.Revert(); } } if (hr == 5 || hr == 1307 || hr == 1308) { throw new UnauthorizedAccessException(); } if (hr == 1314) { throw new PrivilegeNotHeldException("SeSecurityPrivilege"); } if (hr == 6) { throw new NotSupportedException(Environment.GetResourceString("AccessControl_InvalidHandle")); } if (hr != 0) { throw new CryptographicException(hr); } }
/// <summary> /// Tries to generate and RSA Key in the given provider with this keyName. /// </summary> /// <param name="providerName">Name of the provider</param> /// <param name="keyName">Name of the key</param> /// <param name="keyLength">Length of the key to generate</param> /// <returns>true if successful, false if that key already exists.</returns> public bool TryGenerateLocalRSAKey(string providerName, string keyName, int keyLength = 2048) { CngProvider provider = new CngProvider(providerName); bool keyExists = doesKeyExists(provider, keyName); if (keyExists) { //Key already exists. Can't create it. return(false); } CryptoKeySecurity sec = new CryptoKeySecurity(); CngKeyCreationParameters keyParams = null; if (IsMicrosoftSoftwareKSP(provider)) { sec.AddAccessRule( new CryptoKeyAccessRule( new SecurityIdentifier(sidType: WellKnownSidType.BuiltinAdministratorsSid, domainSid: null), cryptoKeyRights: CryptoKeyRights.FullControl, type: AccessControlType.Allow)); sec.AddAccessRule( new CryptoKeyAccessRule( new SecurityIdentifier(sidType: WellKnownSidType.BuiltinSystemOperatorsSid, domainSid: null), cryptoKeyRights: CryptoKeyRights.GenericRead, type: AccessControlType.Allow)); const string NCRYPT_SECURITY_DESCR_PROPERTY = "Security Descr"; const CngPropertyOptions DACL_SECURITY_INFORMATION = (CngPropertyOptions)4; CngProperty permissions = new CngProperty( NCRYPT_SECURITY_DESCR_PROPERTY, sec.GetSecurityDescriptorBinaryForm(), CngPropertyOptions.Persist | DACL_SECURITY_INFORMATION); keyParams = new CngKeyCreationParameters() { ExportPolicy = CngExportPolicies.None, Provider = provider, Parameters = { new CngProperty("Length", BitConverter.GetBytes(keyLength), CngPropertyOptions.None), permissions }, KeyCreationOptions = CngKeyCreationOptions.MachineKey }; using (CngKey key = CngKey.Create(CngAlgorithm.Rsa, keyName, keyParams)) { if (key == null) { return(false); } return(true); } } else { keyParams = new CngKeyCreationParameters() { ExportPolicy = CngExportPolicies.None, Provider = provider, Parameters = { new CngProperty("Length", BitConverter.GetBytes(keyLength), CngPropertyOptions.None) } }; using (CngKey key = CngKey.Create(CngAlgorithm.Rsa, keyName, keyParams)) { if (key == null) { return(false); } // nothing to do inside here, except to return without throwing an exception return(true); } } }
internal static void SetKeySetSecurityInfo(SafeProvHandle hProv, CryptoKeySecurity cryptoKeySecurity, AccessControlSections accessControlSections) { SecurityInfos securityInfo = 0; Privilege privilege = null; if (((accessControlSections & AccessControlSections.Owner) != AccessControlSections.None) && (cryptoKeySecurity._securityDescriptor.Owner != null)) { securityInfo |= SecurityInfos.Owner; } if (((accessControlSections & AccessControlSections.Group) != AccessControlSections.None) && (cryptoKeySecurity._securityDescriptor.Group != null)) { securityInfo |= SecurityInfos.Group; } if ((accessControlSections & AccessControlSections.Audit) != AccessControlSections.None) { securityInfo |= SecurityInfos.SystemAcl; } if (((accessControlSections & AccessControlSections.Access) != AccessControlSections.None) && cryptoKeySecurity._securityDescriptor.IsDiscretionaryAclPresent) { securityInfo |= SecurityInfos.DiscretionaryAcl; } if (securityInfo != 0) { int hr = 0; RuntimeHelpers.PrepareConstrainedRegions(); try { if ((securityInfo & SecurityInfos.SystemAcl) != 0) { privilege = new Privilege("SeSecurityPrivilege"); privilege.Enable(); } byte[] securityDescriptorBinaryForm = cryptoKeySecurity.GetSecurityDescriptorBinaryForm(); if ((securityDescriptorBinaryForm != null) && (securityDescriptorBinaryForm.Length > 0)) { hr = SetKeySetSecurityInfo(hProv, securityInfo, securityDescriptorBinaryForm); } } finally { if (privilege != null) { privilege.Revert(); } } switch (hr) { case 5: case 0x51b: case 0x51c: throw new UnauthorizedAccessException(); case 0x522: throw new PrivilegeNotHeldException("SeSecurityPrivilege"); case 6: throw new NotSupportedException(Environment.GetResourceString("AccessControl_InvalidHandle")); } if (hr != 0) { throw new CryptographicException(hr); } } }