1
0
mirror of https://github.com/twiglet/cs2j.git synced 2025-01-18 13:15:17 +01:00

Add a utility to generate a rsa key pair and a utility to use the private key to sign xml files

This commit is contained in:
Kevin Glynn 2011-03-18 17:28:55 +01:00
parent af022fcbdb
commit 5c65b350b7
7 changed files with 533 additions and 0 deletions

View File

@ -0,0 +1,27 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("CS2JKeyGenerator")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.*")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>10.0.0</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{F294E768-56C3-438A-A3E5-8FA39825262E}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>CS2JKeyGenerator</RootNamespace>
<AssemblyName>CS2JKeyGenerator</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Main.cs" />
<Compile Include="AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<ProjectReference Include="..\NDesk.Options\NDesk.Options.csproj">
<Project>{E6ACBB37-AF38-45E1-B399-0CEE63809A15}</Project>
<Name>NDesk.Options</Name>
</ProjectReference>
</ItemGroup>
</Project>

View File

@ -0,0 +1,102 @@
/*
Copyright 2010,2011 Kevin Glynn (kevin.glynn@twigletsoftware.com)
*/
using System;
using System.Reflection;
using System.IO;
using System.Text;
using NDesk.Options;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Xml;
namespace Twiglet.CS2J.Utility
{
public class KeyGenerator
{
private const string CS2JKEYGEN_VERSION = "pre-release";
private static void printUsageAndExit()
{
Console.Out.WriteLine("Usage: " + Path.GetFileNameWithoutExtension(System.Environment.GetCommandLineArgs()[0]) + " <type to dump, if not given dump all>");
Console.Out.WriteLine(" [-version] (show version information)");
Console.Out.WriteLine(" [-help|h|?] (this usage message)");
Console.Out.WriteLine(" [-v] (be [somewhat more] verbose, repeat for more verbosity)");
Console.Out.WriteLine(" [-keypath <directory>] (directory to place the key files)");
Console.Out.WriteLine(" [-keyname <name>] (name of this key pair, used to name the key files)");
Environment.Exit(0);
}
private static void printVersion()
{
Console.Out.WriteLine(Path.GetFileNameWithoutExtension(System.Environment.GetCommandLineArgs()[0]));
Console.WriteLine("Version: {0}", CS2JKEYGEN_VERSION);
}
public static void Main(string[] args)
{
int Verbose = 0;
RSACryptoServiceProvider RsaKey = null;
string KeyPath = Directory.GetCurrentDirectory();
string KeyName = "rsakey";
OptionSet p = new OptionSet()
.Add("v", v => Verbose++)
.Add("version", v => printVersion())
.Add("help|h|?", v => printUsageAndExit())
.Add("keypath=", dir => KeyPath = Path.GetFullPath(dir))
.Add("keyname=", name => KeyName = name)
;
p.Parse(args);
try
{
// Create a new CspParameters object to specify
// a key container.
CspParameters cspParams = new CspParameters();
cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";
// Create a new RSA signing key and save it in the container.
RsaKey = new RSACryptoServiceProvider(cspParams);
// We don't want to store the key in the csp, and also we don't want to get the same key
// each time.
RsaKey.PersistKeyInCsp = false;
if (!Directory.Exists(KeyPath))
{
Directory.CreateDirectory(KeyPath);
}
XmlWriterSettings set = new XmlWriterSettings();
set.Indent = true;
set.Encoding = Encoding.UTF8;
// Write public key info
XmlWriter xw = XmlWriter.Create(Path.Combine(KeyPath, KeyName + "_pub.xml"), set);
XmlReader reader = XmlReader.Create(new StringReader(RsaKey.ToXmlString(false)));
xw.WriteNode(reader, true);
xw.Close();
// Write public/private key info
xw = XmlWriter.Create(Path.Combine(KeyPath, KeyName + "_priv.xml"), set);
reader = XmlReader.Create(new StringReader(RsaKey.ToXmlString(true)));
xw.WriteNode(reader, true);
xw.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}

View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{DF234BD4-A292-4C92-AC8E-F97D3E821079}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>CS2JTemplateSigner</RootNamespace>
<AssemblyName>CS2JTemplateSigner</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Commandlineparameters>-keyfile /tmp/fred/kg_priv.xml /Users/keving/gitrepos/cs2j/CS2JLibrary/NetFramework/System/Collections/Generic/KeyValuePair\'2.xml</Commandlineparameters>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Security" />
<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="Main.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NDesk.Options\NDesk.Options.csproj">
<Project>{E6ACBB37-AF38-45E1-B399-0CEE63809A15}</Project>
<Name>NDesk.Options</Name>
</ProjectReference>
</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>

View File

@ -0,0 +1,227 @@
/*
Copyright 2010,2011 Kevin Glynn (kevin.glynn@twigletsoftware.com)
*/
using System;
using System.Reflection;
using System.IO;
using System.Xml.Serialization;
using System.Xml;
using System.Text;
using NDesk.Options;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
namespace Twiglet.CS2J.Utility
{
public class TemplateSigner
{
private const string CS2JSIGNER_VERSION = "pre-release";
private int Verbose { get; set; }
public delegate void FileProcessor(string fName);
private List<string> XmlDirs { get; set; }
private List<string> ExcludeXmlDirs { get; set; }
private String KeyFile = null;
RSACryptoServiceProvider RsaKey { get; set; }
public TemplateSigner()
{
Verbose = 0;
XmlDirs = new List<string>();
ExcludeXmlDirs = new List<string>();
RsaKey = null;
}
private static void printUsageAndExit()
{
Console.Out.WriteLine("Usage: " + Path.GetFileNameWithoutExtension(System.Environment.GetCommandLineArgs()[0]) + " <type to dump, if not given dump all>");
Console.Out.WriteLine(" [-version] (show version information)");
Console.Out.WriteLine(" [-help|h|?] (this usage message)");
Console.Out.WriteLine(" [-v] (be [somewhat more] verbose, repeat for more verbosity)");
Console.Out.WriteLine(" [-privkeyfile <path to rsa private key file (xml format)");
Console.Out.WriteLine(" [-xmlpath <a root of xml files to be signed>] (can be multiple directories, separated by semi-colons)");
Console.Out.WriteLine(" [-exxmlpath <directories/files to be excluded from signing>] (can be multiple directories/files, separated by semi-colons)");
Console.Out.WriteLine(" [<root of xml files to be signed>] (can be multiple directories, separated by semi-colons)");
Environment.Exit(0);
}
private static void printVersion()
{
Console.Out.WriteLine(Path.GetFileNameWithoutExtension(System.Environment.GetCommandLineArgs()[0]));
Console.WriteLine("Version: {0}", CS2JSIGNER_VERSION);
}
private static void addDirectories(IList<string> strs, string rawStr)
{
string[] argDirs = rawStr.Split(';');
for (int i = 0; i < argDirs.Length; i++)
strs.Add(Path.GetFullPath(argDirs[i]));
}
public static void Main(string[] args)
{
TemplateSigner templateSigner = new TemplateSigner();
List<string> xmlDirs = new List<string>();
List<string> excludeXmlDirs = new List<string>();
OptionSet p = new OptionSet()
.Add("v", v => templateSigner.Verbose++)
.Add("version", v => printVersion())
.Add("help|h|?", v => printUsageAndExit())
.Add("keyfile=", fname => templateSigner.KeyFile = Path.GetFullPath(fname))
.Add("xmlpath=", dirs => addDirectories(xmlDirs, dirs))
.Add("exxmlpath=", dirs => addDirectories(excludeXmlDirs, dirs))
;
List<string> leftovers = p.Parse(args);
if (leftovers != null)
{
foreach (string d in leftovers)
{
addDirectories(xmlDirs, d);
}
}
templateSigner.XmlDirs = xmlDirs;
templateSigner.ExcludeXmlDirs = excludeXmlDirs;
if (!File.Exists(templateSigner.KeyFile)) {
Console.Out.WriteLine("Error: RSA key at '" + templateSigner.KeyFile + "' not found, aborting.");
Environment.Exit(1);
}
templateSigner.SignXmlFiles();
}
public void SignXmlFiles() {
try
{
XmlReader reader = XmlReader.Create(KeyFile);
reader.MoveToContent();
// Create a new CspParameters object to specify
// a key container.
CspParameters cspParams = new CspParameters();
cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";
// Initialise from .
RsaKey = new RSACryptoServiceProvider(cspParams);
RsaKey.PersistKeyInCsp = false;
RsaKey.FromXmlString(reader.ReadOuterXml());
// Load .Net templates
if (XmlDirs != null)
{
foreach (string r in XmlDirs)
doFile(r, ".xml", SignNetTranslation, ExcludeXmlDirs);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
private void SignNetTranslation(string filePath)
{
// Create a new XML document.
XmlDocument xmlDoc = new XmlDocument();
// Load an XML file into the XmlDocument object.
xmlDoc.PreserveWhitespace = true;
xmlDoc.Load(filePath);
// Sign the XML document.
SignXml(xmlDoc, RsaKey);
Console.WriteLine("XML file signed.");
// Save the document.
xmlDoc.Save(filePath);
}
// Sign an XML file.
// This document cannot be verified unless the verifying
// code has the key with which it was signed.
private void SignXml(XmlDocument xmlDoc, RSA Key)
{
// Check arguments.
if (xmlDoc == null)
throw new ArgumentException("xmlDoc");
if (Key == null)
throw new ArgumentException("Key");
// Add the namespace.
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("ss", "http://www.w3.org/2000/09/xmldsig#");
// Remove any existing signature(s)
XmlNode root = xmlDoc.DocumentElement;
XmlNodeList nodeList = root.SelectNodes("/*/ss:Signature", nsmgr);
for (int i = nodeList.Count - 1; i >= 0; i--)
{
nodeList[i].ParentNode.RemoveChild(nodeList[i]);
}
// Create a SignedXml object.
SignedXml signedXml = new SignedXml(xmlDoc);
// Add the key to the SignedXml document.
signedXml.SigningKey = Key;
// Create a reference to be signed.
Reference reference = new Reference();
reference.Uri = "";
// Add an enveloped transformation to the reference.
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(env);
// Add the reference to the SignedXml object.
signedXml.AddReference(reference);
// Compute the signature.
signedXml.ComputeSignature();
// Get the XML representation of the signature and save
// it to an XmlElement object.
XmlElement xmlDigitalSignature = signedXml.GetXml();
// Append the element to the XML document.
xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
}
// Call processFile on all files below f that have the given extension
private void doFile(string root, string ext, FileProcessor processFile, IList<string> excludes)
{
string canonicalPath = Path.GetFullPath(root);
// If this is a directory, walk each file/dir in that directory
if (!excludes.Contains(canonicalPath.ToLower()))
{
if (Directory.Exists(canonicalPath))
{
string[] files = Directory.GetFileSystemEntries(canonicalPath);
for (int i = 0; i < files.Length; i++)
doFile(Path.Combine(canonicalPath, files[i]), ext, processFile, excludes);
}
else if ((Path.GetFileName(canonicalPath).Length > ext.Length) && canonicalPath.Substring(canonicalPath.Length - ext.Length).Equals(ext))
{
if (Verbose >= 2) Console.WriteLine(" " + canonicalPath);
try
{
processFile(canonicalPath);
}
catch (Exception e)
{
Console.Error.WriteLine("\nCannot process file: " + canonicalPath);
Console.Error.WriteLine("exception: " + e);
}
}
}
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("CS2JTemplateSigner")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CS2JTemplateSigner")]
[assembly: AssemblyCopyright("Copyright © 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("26a927a7-f3de-4603-9719-a2aebb6c7295")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -9,6 +9,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Antlr3.Runtime", "Antlr.Run
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CS2JTemplateGenerator", "CS2JTemplateGenerator\CS2JTemplateGenerator.csproj", "{B72D065B-862A-469B-87F1-2E521AC7CA08}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CS2JTemplateSigner", "CS2JTemplateSigner\CS2JTemplateSigner.csproj", "{DF234BD4-A292-4C92-AC8E-F97D3E821079}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CS2JKeyGenerator", "CS2JKeyGenerator\CS2JKeyGenerator.csproj", "{F294E768-56C3-438A-A3E5-8FA39825262E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -26,6 +30,7 @@ Global
{39949CE9-8C9D-46C2-BE90-37FEE97CCBF9}.Debug|x86.ActiveCfg = Debug|x86
{39949CE9-8C9D-46C2-BE90-37FEE97CCBF9}.Debug|x86.Build.0 = Debug|x86
{39949CE9-8C9D-46C2-BE90-37FEE97CCBF9}.Release|Any CPU.ActiveCfg = Release|x86
{39949CE9-8C9D-46C2-BE90-37FEE97CCBF9}.Release|Any CPU.Build.0 = Release|x86
{39949CE9-8C9D-46C2-BE90-37FEE97CCBF9}.Release|Mixed Platforms.ActiveCfg = Release|x86
{39949CE9-8C9D-46C2-BE90-37FEE97CCBF9}.Release|Mixed Platforms.Build.0 = Release|x86
{39949CE9-8C9D-46C2-BE90-37FEE97CCBF9}.Release|x86.ActiveCfg = Release|x86
@ -51,6 +56,17 @@ Global
{CF15D0D5-BE72-4F98-B70F-229ABA1DF0E8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{CF15D0D5-BE72-4F98-B70F-229ABA1DF0E8}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{CF15D0D5-BE72-4F98-B70F-229ABA1DF0E8}.Release|x86.ActiveCfg = Release|Any CPU
{DF234BD4-A292-4C92-AC8E-F97D3E821079}.Debug|Any CPU.ActiveCfg = Debug|x86
{DF234BD4-A292-4C92-AC8E-F97D3E821079}.Debug|Any CPU.Build.0 = Debug|x86
{DF234BD4-A292-4C92-AC8E-F97D3E821079}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{DF234BD4-A292-4C92-AC8E-F97D3E821079}.Debug|Mixed Platforms.Build.0 = Debug|x86
{DF234BD4-A292-4C92-AC8E-F97D3E821079}.Debug|x86.ActiveCfg = Debug|x86
{DF234BD4-A292-4C92-AC8E-F97D3E821079}.Debug|x86.Build.0 = Debug|x86
{DF234BD4-A292-4C92-AC8E-F97D3E821079}.Release|Any CPU.ActiveCfg = Release|x86
{DF234BD4-A292-4C92-AC8E-F97D3E821079}.Release|Mixed Platforms.ActiveCfg = Release|x86
{DF234BD4-A292-4C92-AC8E-F97D3E821079}.Release|Mixed Platforms.Build.0 = Release|x86
{DF234BD4-A292-4C92-AC8E-F97D3E821079}.Release|x86.ActiveCfg = Release|x86
{DF234BD4-A292-4C92-AC8E-F97D3E821079}.Release|x86.Build.0 = Release|x86
{E6ACBB37-AF38-45E1-B399-0CEE63809A15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E6ACBB37-AF38-45E1-B399-0CEE63809A15}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E6ACBB37-AF38-45E1-B399-0CEE63809A15}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@ -61,6 +77,18 @@ Global
{E6ACBB37-AF38-45E1-B399-0CEE63809A15}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{E6ACBB37-AF38-45E1-B399-0CEE63809A15}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{E6ACBB37-AF38-45E1-B399-0CEE63809A15}.Release|x86.ActiveCfg = Release|Any CPU
{F294E768-56C3-438A-A3E5-8FA39825262E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F294E768-56C3-438A-A3E5-8FA39825262E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F294E768-56C3-438A-A3E5-8FA39825262E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{F294E768-56C3-438A-A3E5-8FA39825262E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{F294E768-56C3-438A-A3E5-8FA39825262E}.Debug|x86.ActiveCfg = Debug|Any CPU
{F294E768-56C3-438A-A3E5-8FA39825262E}.Debug|x86.Build.0 = Debug|Any CPU
{F294E768-56C3-438A-A3E5-8FA39825262E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F294E768-56C3-438A-A3E5-8FA39825262E}.Release|Any CPU.Build.0 = Release|Any CPU
{F294E768-56C3-438A-A3E5-8FA39825262E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{F294E768-56C3-438A-A3E5-8FA39825262E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{F294E768-56C3-438A-A3E5-8FA39825262E}.Release|x86.ActiveCfg = Release|Any CPU
{F294E768-56C3-438A-A3E5-8FA39825262E}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = CS2JTranslator\CS2JTranslator.csproj