From b979e42bca81d21e63947f7384f947d956cf263f Mon Sep 17 00:00:00 2001
From: lhyqy5 <lhyqy5@gmail.com>
Date: Wed, 21 Jan 2015 10:31:52 +0800
Subject: [PATCH] refactor code

---
 .../CertPolicyAppender.cs                     | 207 ++++++++----------
 .../SoftCertPolicyAppender/Program.cs         |  51 +++--
 2 files changed, 122 insertions(+), 136 deletions(-)

diff --git a/Windows/SoftCertPolicyAppender/SoftCertPolicyAppender/SoftCertPolicyAppender/CertPolicyAppender.cs b/Windows/SoftCertPolicyAppender/SoftCertPolicyAppender/SoftCertPolicyAppender/CertPolicyAppender.cs
index 802e88e..86f90fc 100644
--- a/Windows/SoftCertPolicyAppender/SoftCertPolicyAppender/SoftCertPolicyAppender/CertPolicyAppender.cs
+++ b/Windows/SoftCertPolicyAppender/SoftCertPolicyAppender/SoftCertPolicyAppender/CertPolicyAppender.cs
@@ -7,60 +7,38 @@ using Microsoft.Win32;
 
 namespace SoftCertPolicyAppender
 {
-    public class CertPolicyAppender
+    public class SoftwareRestrictionPolicyController
     {
-        public void Load(string certFile)
-        {
-            var cert = new X509Certificate2();
-            cert.Import(certFile);
-            Certificate = cert;
 
+        /// <remarks>引用组件来自:https://bitbucket.org/MartinEden/local-policy/overview </remarks>
+        private static void DeletePolicyKey(string path)
+        {
+            var gpo = new ComputerGroupPolicyObject();
+            using (var machine = gpo.GetRootRegistryKey(GroupPolicySection.Machine))
+            {
+                machine.DeleteSubKey(path, false);
+            }
+            gpo.Save();
         }
 
-        public X509Certificate2 Certificate { get; private set; }
-
-        /// <summary>
-        /// 构造写写入注册表的证书数据
-        /// </summary>
-        /// <returns></returns>
-        private byte[] CalcRegCertData()
+        /// <remarks>引用组件来自:https://bitbucket.org/MartinEden/local-policy/overview </remarks>
+        private static void SetPolicyKey(string path, string name, object value, RegistryValueKind kind)
         {
-            var cert = Certificate;
-            var thumbprintData = cert.Thumbprint.HexString2Bytes().ToArray();
-
-            var rtn = new List<byte>();
-
-            //添加数据头,格式是根据注册表的数据推算的,未注释部分为未知
-            rtn.AddRange(BitConverter.GetBytes(3)); //可能为版本号
-            rtn.AddRange(BitConverter.GetBytes(1)); //可能为次版本号
-            rtn.AddRange(BitConverter.GetBytes(thumbprintData.Length)); //证书宅指纹长度
-            rtn.AddRange(thumbprintData);           //证书指纹数据
-            rtn.AddRange(BitConverter.GetBytes(0x0d));
-            rtn.AddRange(BitConverter.GetBytes(1));
-            rtn.AddRange(BitConverter.GetBytes((short)2));
-            rtn.AddRange(BitConverter.GetBytes(0));
-            rtn.AddRange(BitConverter.GetBytes(0x1b));
-            rtn.AddRange(BitConverter.GetBytes(1));
-            rtn.AddRange(BitConverter.GetBytes(8));
-            rtn.AddRange(BitConverter.GetBytes(DateTime.Now.ToFileTime())); //时间戳
-            rtn.AddRange(BitConverter.GetBytes(0x20));
-            rtn.AddRange(BitConverter.GetBytes(1));
-            rtn.AddRange(BitConverter.GetBytes(cert.RawData.Length)); //证书长度
-            //添加证书数据
-            rtn.AddRange(cert.RawData);
-
-            return rtn.ToArray();
+            var gpo = new ComputerGroupPolicyObject();
+            using (var machine = gpo.GetRootRegistryKey(GroupPolicySection.Machine))
+            {
+                using (var cerKey = machine.CreateSubKey(path))
+                {
+                    if (cerKey != null) cerKey.SetValue(name, value, kind);
+                }
+            }
+            gpo.Save();
         }
 
-        /// <summary>
-        /// 写入注册表项
-        /// </summary>
-        /// <returns></returns>
-        public void WriteRegisty()
+        private static void SetPolicyRegistryKey(string path, string name, object value, RegistryValueKind kind)
         {
-            var cer = Certificate;
             const string keyPath = @"Software\Microsoft\Windows\CurrentVersion\Group Policy Objects";
-            using(var rk = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default))
+            using (var rk = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default))
             {
                 List<string> certKeys;
                 using (var srk = rk.OpenSubKey(keyPath))
@@ -69,27 +47,24 @@ namespace SoftCertPolicyAppender
                     {
                         throw new ApplicationException("无法打开注册表项:" + keyPath);
                     }
-                    certKeys = srk.GetSubKeyNames().Where(x => x.EndsWith("Machine")).Select(x => string.Format("{0}\\{1}\\Software\\Policies\\Microsoft\\SystemCertificates\\Disallowed\\Certificates\\{2}", keyPath, x, cer.Thumbprint))
+                    certKeys = srk.GetSubKeyNames().Where(x => x.EndsWith("Machine")).Select(x => string.Format("{0}\\{1}\\{2}", keyPath, x, path))
                         //.Where(x => rk.OpenSubKey(x) == null)
                         .ToList();
                 }
 
                 foreach (var key in certKeys)
                 {
-                    using (var skey=rk.CreateSubKey(key))
+                    using (var skey = rk.CreateSubKey(key))
                     {
-                        if (skey != null) skey.SetValue("Blob", CalcRegCertData(), RegistryValueKind.Binary);
-                    }                  
+                        if (skey != null) skey.SetValue(name, value, kind);
+                    }
                 }
             }
 
         }
 
-
-
-        public void RemoveRegisty()
+        private static void DeletePolicyRegistryKey(string path)
         {
-            var cer = Certificate;
             const string keyPath = @"Software\Microsoft\Windows\CurrentVersion\Group Policy Objects";
             using (var rk = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default))
             {
@@ -100,96 +75,94 @@ namespace SoftCertPolicyAppender
                     {
                         throw new ApplicationException("无法打开注册表项:" + keyPath);
                     }
-                    certKeys = srk.GetSubKeyNames().Where(x => x.EndsWith("Machine")).Select(x => string.Format("{0}\\{1}\\Software\\Policies\\Microsoft\\SystemCertificates\\Disallowed\\Certificates\\{2}", keyPath, x, cer.Thumbprint))
+                    certKeys = srk.GetSubKeyNames().Where(x => x.EndsWith("Machine")).Select(x => string.Format("{0}\\{1}\\{2}", keyPath, x, path))
                         //.Where(x => rk.OpenSubKey(x) == null)
                         .ToList();
                 }
 
-                foreach (var certKey in certKeys)
+                foreach (var key in certKeys)
                 {
-                    rk.DeleteSubKey(certKey,false);
+                    rk.DeleteSubKey(key, false);
                 }
             }
-        }
 
+        }
 
 
         /// <summary>
-        /// 添加证书组策略
+        /// 构造写写入注册表的证书数据
         /// </summary>
-        /// <remarks>引用组件来自:https://bitbucket.org/MartinEden/local-policy/overview </remarks>
-        public void AddCertPolicy()
+        /// <returns></returns>
+        private static byte[] CalcRegCertData(X509Certificate2 cert)
         {
-            var cert = Certificate;
+            var thumbprintData = cert.Thumbprint.HexString2Bytes().ToArray();
 
-            var gpo = new ComputerGroupPolicyObject();
-            var keyPath = string.Format("Software\\Policies\\Microsoft\\SystemCertificates\\Disallowed\\Certificates\\{0}", cert.Thumbprint);
-            using (var machine = gpo.GetRootRegistryKey(GroupPolicySection.Machine))
-            {
-                using (var cerKey = machine.CreateSubKey(keyPath))
-                {
-                    if (cerKey != null) cerKey.SetValue("Blob", CalcRegCertData(), RegistryValueKind.Binary);
-                }
-            }
-            gpo.Save();
+            var rtn = new List<byte>();
 
-        }
+            //添加数据头,格式是根据注册表的数据推算的,未注释部分为未知
+            rtn.AddRange(BitConverter.GetBytes(3)); //可能为版本号
+            rtn.AddRange(BitConverter.GetBytes(1)); //可能为次版本号
+            rtn.AddRange(BitConverter.GetBytes(thumbprintData.Length)); //证书宅指纹长度
+            rtn.AddRange(thumbprintData);           //证书指纹数据
+            rtn.AddRange(BitConverter.GetBytes(0x0d));
+            rtn.AddRange(BitConverter.GetBytes(1));
+            rtn.AddRange(BitConverter.GetBytes((short)2));
+            rtn.AddRange(BitConverter.GetBytes(0));
+            rtn.AddRange(BitConverter.GetBytes(0x1b));
+            rtn.AddRange(BitConverter.GetBytes(1));
+            rtn.AddRange(BitConverter.GetBytes(8));
+            rtn.AddRange(BitConverter.GetBytes(DateTime.Now.ToFileTime())); //时间戳
+            rtn.AddRange(BitConverter.GetBytes(0x20));
+            rtn.AddRange(BitConverter.GetBytes(1));
+            rtn.AddRange(BitConverter.GetBytes(cert.RawData.Length)); //证书长度
+            //添加证书数据
+            rtn.AddRange(cert.RawData);
 
+            return rtn.ToArray();
+        }
 
-        public void RemoveCertPolicy()
+     
+        /// <summary>
+        /// 添加证书规则
+        /// </summary>
+        /// <param name="cert"></param>
+        public static void AddCertRule(X509Certificate2 cert)
         {
-            var cert = Certificate;
-
-            var gpo = new ComputerGroupPolicyObject();
             var keyPath = string.Format("Software\\Policies\\Microsoft\\SystemCertificates\\Disallowed\\Certificates\\{0}", cert.Thumbprint);
-            using (var machine = gpo.GetRootRegistryKey(GroupPolicySection.Machine))
-            {
-                machine.DeleteSubKey(keyPath,false);
-            }
-            gpo.Save();
-
+            const string keyName = "Blob";
+            const RegistryValueKind kind = RegistryValueKind.Binary;
+            var value = CalcRegCertData(cert);          
+            SetPolicyKey(keyPath, keyName,value,kind);
+            SetPolicyRegistryKey(keyPath,keyName,value,kind);
         }
 
-        public void SetForcePolicyStat(bool enable)
+
+        /// <summary>
+        /// 移除证书规则
+        /// </summary>
+        /// <param name="cert"></param>
+        public static void RemoveCertRule(X509Certificate2 cert)
         {
-            var gpo = new ComputerGroupPolicyObject();
-            const string keyPath = "Software\\Policies\\Microsoft\\Windows\\Safer\\CodeIdentifiers";
-            using (var machine = gpo.GetRootRegistryKey(GroupPolicySection.Machine))
-            {
-                using (var cerKey = machine.CreateSubKey(keyPath))
-                {
-                    cerKey.SetValue("AuthenticodeEnabled", enable ? 1 : 0, RegistryValueKind.DWord);
-                }
-            }
-            gpo.Save();
+            var keyPath = string.Format("Software\\Policies\\Microsoft\\SystemCertificates\\Disallowed\\Certificates\\{0}", cert.Thumbprint);
+            DeletePolicyKey(keyPath);
+            DeletePolicyRegistryKey(keyPath);
         }
 
-        public void SetForceRegistryPolicyStat(bool enable)
-        {
-            const string keyPath = @"Software\Microsoft\Windows\CurrentVersion\Group Policy Objects";
-            using (var rk = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default))
-            {
-                List<string> certKeys;
-                using (var srk = rk.OpenSubKey(keyPath))
-                {
-                    if (srk == null)
-                    {
-                        throw new ApplicationException("无法打开注册表项:" + keyPath);
-                    }
-                    certKeys = srk.GetSubKeyNames().Where(x => x.EndsWith("Machine")).Select(x => string.Format("{0}\\{1}\\Software\\Policies\\Microsoft\\Windows\\Safer\\CodeIdentifiers", keyPath, x))
-                        //.Where(x => rk.OpenSubKey(x) == null)
-                        .ToList();
-                }
 
-                foreach (var key in certKeys)
-                {
-                    using (var skey = rk.CreateSubKey(key))
-                    {
-                        if (skey != null) skey.SetValue("AuthenticodeEnabled", enable ? 1 : 0, RegistryValueKind.DWord);
-                    }
-                }
-            }
+        /// <summary>
+        /// 设置是否启用强制策略
+        /// </summary>
+        /// <param name="enable"></param>
+        public static void SetForcePolicyState(bool enable)
+        {
+            const string keyPath = "Software\\Policies\\Microsoft\\Windows\\Safer\\CodeIdentifiers";
+            const string keyName = "AuthenticodeEnabled";
+            const RegistryValueKind kind = RegistryValueKind.DWord;
+            var value = enable ? 1 : 0;
+            SetPolicyKey(keyPath, keyName, value, kind);
+            SetPolicyRegistryKey(keyPath, keyName, value, kind);
         }
+
     }
 
 
diff --git a/Windows/SoftCertPolicyAppender/SoftCertPolicyAppender/SoftCertPolicyAppender/Program.cs b/Windows/SoftCertPolicyAppender/SoftCertPolicyAppender/SoftCertPolicyAppender/Program.cs
index 323c6b5..7e11e1e 100644
--- a/Windows/SoftCertPolicyAppender/SoftCertPolicyAppender/SoftCertPolicyAppender/Program.cs
+++ b/Windows/SoftCertPolicyAppender/SoftCertPolicyAppender/SoftCertPolicyAppender/Program.cs
@@ -1,5 +1,6 @@
 using System;
 using System.Linq;
+using System.Security.Cryptography.X509Certificates;
 
 namespace SoftCertPolicyAppender
 {
@@ -10,6 +11,23 @@ namespace SoftCertPolicyAppender
         {
             var flag = 0;
             var cers = args.Where(x => x.EndsWith(".cer") || x.EndsWith(".crt") || x.EndsWith(".pem")).ToArray();
+
+            if (args.Contains("-h") || args.Contains("--help")||args.Length==0)
+            {
+                const string usage = @"Usage:SoftwareRestrictionPolicyController.exe [OPTOION]... [CERTFILE]...
+config software restriction policy by cli
+
+OPTIONs
+  --set-force      set force certificate policy
+  --unset-force    unset force certificate policy
+  -r               remove certificate rule by CERTFILEs not add
+CERTFILEs
+  certificate file path that will add certificate rule
+";
+                Console.Write(usage);
+                return;
+            }
+
             if (args.Contains("-r"))
             {
                 flag = 1;
@@ -17,45 +35,40 @@ namespace SoftCertPolicyAppender
 
             if (args.Contains("--set-force"))
             {
-                var appender = new CertPolicyAppender ();
-                appender.SetForceRegistryPolicyStat (true);
-                appender.SetForcePolicyStat (true);
+                SoftwareRestrictionPolicyController.SetForcePolicyState(true);
                 Console.WriteLine("Apply force certificate policy");
             }
 
             if (args.Contains("--unset-force"))
             {
-                var appender = new CertPolicyAppender ();
-                appender.SetForceRegistryPolicyStat (false);
-                appender.SetForcePolicyStat (false);
+                SoftwareRestrictionPolicyController.SetForcePolicyState(false);
                 Console.WriteLine("Cancel force certificate policy");
             }
 
-            for (var i=0 ;i<cers.Length;i++)
+            for (var i = 0; i < cers.Length; i++)
             {
                 try
                 {
-                    var appdender = new CertPolicyAppender();
-                    appdender.Load(cers[i]);
+                    var cert = new X509Certificate2(cers[i]);
+
                     Console.ForegroundColor = ConsoleColor.DarkGreen;
-                    Console.Write("{0}.",i+1);
+                    Console.Write("{0}.", i + 1);
                     Console.ResetColor();
+
                     switch (flag)
                     {
                         case 0:
-                            appdender.WriteRegisty();
-                            appdender.AddCertPolicy();
-                        Console.Write("Add cert policy for ");
-
+                            SoftwareRestrictionPolicyController.AddCertRule(cert);
+                            Console.Write("Add cert policy for ");
                             break;
                         case 1:
-                            appdender.RemoveRegisty();
-                            appdender.RemoveCertPolicy();
-                        Console.Write("Remove cert policy for ");
-                            break;                            
+                            SoftwareRestrictionPolicyController.RemoveCertRule(cert);
+                            Console.Write("Remove cert policy for ");
+                            break;
                     }
+
                     Console.ForegroundColor = ConsoleColor.Yellow;
-                    Console.WriteLine("{0}({1})",appdender.Certificate.Subject,appdender.Certificate.Thumbprint);
+                    Console.WriteLine("{0}({1})", cert.Subject, cert.Thumbprint);
                     Console.ResetColor();
                 }
                 catch (Exception e)
-- 
GitLab