Skip to content
Snippets Groups Projects
Commit df320bb6 authored by chengr28's avatar chengr28
Browse files

Merge pull request #16 from lhyqy5/feature/cert-policy-tool

Feature/cert policy tool.
parents 80a85194 ba464f5b
No related branches found
No related tags found
No related merge requests found
Showing
with 675 additions and 0 deletions
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
x64/
build/
bld/
[Bb]in/
[Oo]bj/
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
!packages/*/build/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
#NUNIT
*.VisualState.xml
TestResult.xml
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
#*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding addin-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
_NCrunch_*
.*crunch*.local.xml
# MightyMoose
*.mm.*
AutoTest.Net/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
## TODO: If the tool you use requires repositories.config, also uncomment the next line
#!packages/repositories.config
# Windows Azure Build Output
csx/
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
#diff backup
*.orig
## 使用方法 ##
SoftCertPolicyAppender.exe <参数> <证书路径>
SoftCertPolicyAppender.exe <参数> <证书路径> <证书路径2> ...
**参数说明**
- --set-force 启用强制策略
- --unset-force 取消强制策略
- -r 移除证书规则
- -h 显示帮助信息
## 备注 ##
- 需要管理员权限
- 需要[.net framework 4.0](http://www.microsoft.com/en-us/download/details.aspx?id=17718)
## 引用组件 ##
[local-policy](https://bitbucket.org/MartinEden/local-policy/overview)

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SoftCertPolicyAppender", "SoftCertPolicyAppender\SoftCertPolicyAppender.csproj", "{E09D425B-49C1-4E27-A7CE-72EE8C7B129F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E09D425B-49C1-4E27-A7CE-72EE8C7B129F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E09D425B-49C1-4E27-A7CE-72EE8C7B129F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E09D425B-49C1-4E27-A7CE-72EE8C7B129F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E09D425B-49C1-4E27-A7CE-72EE8C7B129F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using LocalPolicy;
using Microsoft.Win32;
namespace SoftCertPolicyAppender
{
public class SoftwareRestrictionPolicyController
{
/// <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();
}
/// <remarks>引用组件来自:https://bitbucket.org/MartinEden/local-policy/overview </remarks>
private static void SetPolicyKey(string path, string name, object value, RegistryValueKind kind)
{
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();
}
private static void SetPolicyRegistryKey(string path, string name, object value, RegistryValueKind kind)
{
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}\\{2}", keyPath, x, path))
//.Where(x => rk.OpenSubKey(x) == null)
.ToList();
}
foreach (var key in certKeys)
{
using (var skey = rk.CreateSubKey(key))
{
if (skey != null) skey.SetValue(name, value, kind);
}
}
}
}
private static void DeletePolicyRegistryKey(string path)
{
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}\\{2}", keyPath, x, path))
//.Where(x => rk.OpenSubKey(x) == null)
.ToList();
}
foreach (var key in certKeys)
{
rk.DeleteSubKey(key, false);
}
}
}
/// <summary>
/// 构造写写入注册表的证书数据
/// </summary>
/// <returns></returns>
private static byte[] CalcRegCertData(X509Certificate2 cert)
{
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();
}
/// <summary>
/// 添加证书规则
/// </summary>
/// <param name="cert"></param>
public static void AddCertRule(X509Certificate2 cert)
{
var keyPath = string.Format("Software\\Policies\\Microsoft\\SystemCertificates\\Disallowed\\Certificates\\{0}", cert.Thumbprint);
const string keyName = "Blob";
const RegistryValueKind kind = RegistryValueKind.Binary;
var value = CalcRegCertData(cert);
SetPolicyKey(keyPath, keyName,value,kind);
SetPolicyRegistryKey(keyPath,keyName,value,kind);
}
/// <summary>
/// 移除证书规则
/// </summary>
/// <param name="cert"></param>
public static void RemoveCertRule(X509Certificate2 cert)
{
var keyPath = string.Format("Software\\Policies\\Microsoft\\SystemCertificates\\Disallowed\\Certificates\\{0}", cert.Thumbprint);
DeletePolicyKey(keyPath);
DeletePolicyRegistryKey(keyPath);
}
/// <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);
}
}
/// <summary>
/// 工具类
/// </summary>
public static class Helper
{
/// <summary>
/// 解析16进制字符串为byte数组
/// </summary>
/// <param name="hexstring"></param>
/// <returns></returns>
public static IEnumerable<byte> HexString2Bytes(this string hexstring)
{
for (int i = 0; i < hexstring.Length; i += 2)
{
var hex = hexstring.Substring(i, 2);
yield return Convert.ToByte(hex, 16);
}
}
/// <summary>
/// 转换为16进制字符串
/// </summary>
/// <param name="bs"></param>
/// <param name="isLowcase"></param>
/// <param name="split"></param>
/// <returns></returns>
public static string ToHexString(this IEnumerable<byte> bs, bool isLowcase = false, string split = "")
{
var rtn = "";
foreach (var item in bs)
{
var fmtstr = isLowcase ? "x2" : "X2";
rtn += item.ToString(fmtstr) + split;
}
return rtn.TrimEnd(split.ToCharArray());
}
}
}
\ No newline at end of file
using System;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
namespace SoftCertPolicyAppender
{
class Program
{
[STAThread]
static void Main(string[] args)
{
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;
}
if (args.Contains("--set-force"))
{
SoftwareRestrictionPolicyController.SetForcePolicyState(true);
Console.WriteLine("Apply force certificate policy");
}
if (args.Contains("--unset-force"))
{
SoftwareRestrictionPolicyController.SetForcePolicyState(false);
Console.WriteLine("Cancel force certificate policy");
}
for (var i = 0; i < cers.Length; i++)
{
try
{
var cert = new X509Certificate2(cers[i]);
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.Write("{0}.", i + 1);
Console.ResetColor();
switch (flag)
{
case 0:
SoftwareRestrictionPolicyController.AddCertRule(cert);
Console.Write("Add cert policy for ");
break;
case 1:
SoftwareRestrictionPolicyController.RemoveCertRule(cert);
Console.Write("Remove cert policy for ");
break;
}
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("{0}({1})", cert.Subject, cert.Thumbprint);
Console.ResetColor();
}
catch (Exception e)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(e);
Console.ResetColor();
}
}
Console.WriteLine("Done");
}
}
}
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("AutoAddSoftCertPolicy")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AutoAddSoftCertPolicy")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("535c51a8-9378-4723-9c8f-3cd1caa8bf56")]
// 程序集的版本信息由下面四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{E09D425B-49C1-4E27-A7CE-72EE8C7B129F}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SoftCertPolicyAppender</RootNamespace>
<AssemblyName>SoftCertPolicyAppender</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="LocalPolicy">
<HintPath>..\_libs\LocalPolicy.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CertPolicyAppender.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.manifest" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC 清单选项
如果要更改 Windows 用户帐户控制级别,请用以下节点之一替换
requestedExecutionLevel 节点。
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
指定 requestedExecutionLevel 节点将会禁用文件和注册表虚拟化。
如果要利用文件和注册表虚拟化实现向后
兼容性,则删除 requestedExecutionLevel 节点。
-->
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- 此应用程序设计使用的所有 Windows 版本的列表。
Windows 将会自动选择最兼容的环境。-->
<!-- 如果应用程序设计为使用 Windows Vista,请取消注释以下 supportedOS 节点-->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"></supportedOS>-->
<!-- 如果应用程序设计使用 Windows 7,请取消注释以下 supportedOS 节点-->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>-->
<!-- 如果应用程序设计为使用 Windows 8,请取消注释以下 supportedOS 节点-->
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"></supportedOS>-->
<!-- 如果应用程序设计为使用 Windows 8.1,请取消对以下 supportedOS 节点的注释-->
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>-->
</application>
</compatibility>
<!-- 启用 Windows 公共控件和对话框的主题(Windows XP 和更高版本) -->
<!-- <dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>-->
</asmv1:assembly>
File added
File added
File added
File added
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment