Begin to implement RSA key DataFormat/ObjectModel

This commit is contained in:
Michael Becker 2015-04-17 13:03:17 -04:00
parent 651ed11d9e
commit 6c3e3eaf5e
24 changed files with 253 additions and 3 deletions

View File

@ -177,14 +177,14 @@ namespace UniversalEditor.UserInterface.WindowsForms.Dialogs
private void dlgAccessor_SelectionChanged(object sender, EventArgs e)
{
GenericBrowserPopup<Accessor, AccessorReference> dlg = (sender as GenericBrowserPopup<Accessor, AccessorReference>);
mvarAccessor = dlg.SelectedObject;
Accessor acc = dlg.SelectedObject;
dlg.AutoClose = false;
switch (mvarMode)
{
case DocumentPropertiesDialogMode.Open:
{
if (!Engine.CurrentEngine.ShowCustomOptionDialog(ref mvarAccessor, CustomOptionDialogType.Import))
if (!Engine.CurrentEngine.ShowCustomOptionDialog(ref acc, CustomOptionDialogType.Import))
{
return;
}
@ -192,7 +192,7 @@ namespace UniversalEditor.UserInterface.WindowsForms.Dialogs
}
case DocumentPropertiesDialogMode.Save:
{
if (!Engine.CurrentEngine.ShowCustomOptionDialog(ref mvarAccessor, CustomOptionDialogType.Export))
if (!Engine.CurrentEngine.ShowCustomOptionDialog(ref acc, CustomOptionDialogType.Export))
{
return;
}
@ -200,6 +200,7 @@ namespace UniversalEditor.UserInterface.WindowsForms.Dialogs
}
}
mvarAccessor = acc;
RefreshButtons();
dlg.AutoClose = true;
@ -308,6 +309,10 @@ namespace UniversalEditor.UserInterface.WindowsForms.Dialogs
{
txtAccessor.Text = mvarAccessor.ToString();
}
else
{
txtAccessor.Text = String.Empty;
}
if (mvarDataFormat != null)
{
DataFormatReference dfr = mvarDataFormat.MakeReference();

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UniversalEditor.DataFormats.Security.Key.RSA
{
public enum RSAKeyAlgorithm : uint
{
KeyX = 0x0000A400,
Sign = 0x00002400
}
}

View File

@ -0,0 +1,128 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UniversalEditor.IO;
using UniversalEditor.ObjectModels.Security.Key.RSA;
namespace UniversalEditor.DataFormats.Security.Key.RSA
{
public class RSAKeyDataFormat : DataFormat
{
private static DataFormatReference _dfr = null;
protected override DataFormatReference MakeReferenceInternal()
{
if (_dfr == null)
{
_dfr = base.MakeReferenceInternal();
_dfr.Capabilities.Add(typeof(RSAKeyObjectModel), DataFormatCapabilities.All);
}
return _dfr;
}
private byte mvarFormatVersion = 0x02;
public byte FormatVersion { get { return mvarFormatVersion; } set { mvarFormatVersion = value; } }
protected override void LoadInternal(ref ObjectModel objectModel)
{
RSAKeyObjectModel key = (objectModel as RSAKeyObjectModel);
if (key == null) throw new ObjectModelNotSupportedException();
Reader reader = base.Accessor.Reader;
// ---- read the BLOBHEADER struct ------
bool dotnetkey = false;
RSAKeyType btype = (RSAKeyType)reader.ReadByte();
if (btype != RSAKeyType.PublicKeyBlob && btype != RSAKeyType.PrivateKeyBlob)
{
// possibly a .NET publickey
reader.Accessor.Seek(11, SeekOrigin.Current); // advance past 3 int headers, minus 1 byte read
btype = (RSAKeyType)reader.ReadByte();
if (btype != RSAKeyType.PublicKeyBlob && btype != RSAKeyType.PrivateKeyBlob)
{
throw new InvalidDataFormatException("Key is neither a PublicKeyBlob nor a PrivateKeyBlob");
}
dotnetkey = true;
}
byte version = reader.ReadByte();
if (version != mvarFormatVersion)
{
throw new InvalidDataFormatException("Invalid version for format " + version.ToString());
}
ushort reserved = reader.ReadUInt16();
RSAKeyAlgorithm algorithm = (RSAKeyAlgorithm)reader.ReadUInt32();
if (algorithm != RSAKeyAlgorithm.KeyX && algorithm != RSAKeyAlgorithm.Sign)
{
throw new InvalidDataFormatException("Unknown algorithm " + algorithm.ToString());
}
//---- read the RSAPUBKEY struct --------
string magic = reader.ReadFixedLengthString(4);
if (magic != "RSA1" && magic != "RSA2")
{
throw new InvalidDataFormatException("File does not begin with 'RSA1' or 'RSA2'");
}
int bitlen = reader.ReadInt32(); //get RSA bit length
key.BitLength = bitlen;
//---- read RSA public exponent ------
reader.Endianness = Endianness.BigEndian;
uint pubexp = reader.ReadUInt32(); //get public exponent
key.PublicExponent = pubexp;
//---- read RSA modulus -----------
//Reverse byte array for little-endian to big-endian conversion
byte[] RSAmodulus = reader.ReadBytes(bitlen / 8);
Array.Reverse(RSAmodulus);
key.Modulus = RSAmodulus;
//-- if this is a valid unencrypted PRIVATEKEYBLOB, read RSA private key properties
if (btype == RSAKeyType.PrivateKeyBlob)
{
int bitlen16 = bitlen / 16;
byte[] P = reader.ReadBytes(bitlen16);
Array.Reverse(P);
if (P.Length != bitlen16)
throw new InvalidDataFormatException("Invalid bit length for P");
key.P = P;
byte[] Q = reader.ReadBytes(bitlen16);
Array.Reverse(Q);
if (Q.Length != bitlen16)
throw new InvalidDataFormatException("Invalid bit length for Q");
key.Q = Q;
byte[] DP = reader.ReadBytes(bitlen16);
Array.Reverse(DP);
if (DP.Length != bitlen16)
throw new InvalidDataFormatException("Invalid bit length for DP");
key.DP = DP;
byte[] DQ = reader.ReadBytes(bitlen16);
Array.Reverse(DQ);
if (DQ.Length != bitlen16)
throw new InvalidDataFormatException("Invalid bit length for DQ");
key.DQ = DQ;
byte[] IQ = reader.ReadBytes(bitlen16);
Array.Reverse(IQ);
if (IQ.Length != bitlen16)
throw new InvalidDataFormatException("Invalid bit length for IQ");
key.IQ = IQ;
byte[] D = reader.ReadBytes(bitlen / 8);
Array.Reverse(D);
if (D.Length != bitlen / 8)
throw new InvalidDataFormatException("Invalid bit length for D");
key.D = D;
}
}
protected override void SaveInternal(ObjectModel objectModel)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UniversalEditor.DataFormats.Security.Key.RSA
{
public enum RSAKeyType : byte
{
Simple = 0x01,
PublicKeyBlob = 0x06,
PrivateKeyBlob = 0x07,
PlainTextKeyBlob = 0x08,
OpaqueKeyBlob = 0x09,
PublicKeyBlobEx = 0x0A,
SymmetricWrapKeyBlob = 0x0B
}
}

View File

@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UniversalEditor.ObjectModels.Security.Key.RSA
{
public class RSAKeyObjectModel : ObjectModel
{
private static ObjectModelReference _omr = null;
protected override ObjectModelReference MakeReferenceInternal()
{
if (_omr == null)
{
_omr = base.MakeReferenceInternal();
_omr.Title = "RSA cryptography key";
_omr.Path = new string[] { "Security", "Key" };
}
return _omr;
}
private byte[] mvarP = new byte[0];
public byte[] P { get { return mvarP; } set { mvarP = value; } }
private byte[] mvarQ = new byte[0];
public byte[] Q { get { return mvarQ; } set { mvarQ = value; } }
private byte[] mvarDP = new byte[0];
public byte[] DP { get { return mvarDP; } set { mvarDP = value; } }
private byte[] mvarDQ = new byte[0];
public byte[] DQ { get { return mvarDQ; } set { mvarDQ = value; } }
private byte[] mvarIQ = new byte[0];
public byte[] IQ { get { return mvarIQ; } set { mvarIQ = value; } }
private byte[] mvarD = new byte[0];
public byte[] D { get { return mvarD; } set { mvarD = value; } }
private int mvarBitLength = 0;
/// <summary>
/// The bit length of the private key components.
/// </summary>
public int BitLength { get { return mvarBitLength; } set { mvarBitLength = value; } }
private uint mvarPublicExponent = 0;
/// <summary>
/// The exponent of the public key.
/// </summary>
public uint PublicExponent { get { return mvarPublicExponent; } set { mvarPublicExponent = value; } }
private byte[] mvarModulus = new byte[0];
/// <summary>
/// The RSA modulus.
/// </summary>
public byte[] Modulus { get { return mvarModulus; } set { mvarModulus = value; } }
public override void Clear()
{
mvarBitLength = 0;
mvarD = new byte[0];
mvarDP = new byte[0];
mvarDQ = new byte[0];
mvarIQ = new byte[0];
mvarModulus = new byte[0];
mvarP = new byte[0];
mvarPublicExponent = 0;
mvarQ = new byte[0];
}
public override void CopyTo(ObjectModel where)
{
RSAKeyObjectModel clone = (where as RSAKeyObjectModel);
if (clone == null) throw new ObjectModelNotSupportedException();
clone.BitLength = mvarBitLength;
clone.D = mvarD;
clone.DP = mvarDP;
clone.DQ = mvarDQ;
clone.IQ = mvarIQ;
clone.Modulus = mvarModulus;
clone.P = mvarP;
clone.PublicExponent = mvarPublicExponent;
clone.Q = mvarQ;
}
}
}

View File

@ -62,6 +62,9 @@
<Compile Include="DataFormats\PropertyList\XML\XMLPropertyListDataFormat.cs" />
<Compile Include="DataFormats\RichTextMarkup\RTML\RTMLSettings.cs" />
<Compile Include="DataFormats\Security\Certificate\DER\DERCertificateDataFormat.cs" />
<Compile Include="DataFormats\Security\Key\RSA\RSAKeyAlgorithm.cs" />
<Compile Include="DataFormats\Security\Key\RSA\RSAKeyDataFormat.cs" />
<Compile Include="DataFormats\Security\Key\RSA\RSAKeyType.cs" />
<Compile Include="DataFormats\Shortcut\FreeDesktop\DesktopShortcutAction.cs" />
<Compile Include="DataFormats\Shortcut\FreeDesktop\DesktopShortcutDataFormat.cs" />
<Compile Include="DataFormats\Shortcut\FreeDesktop\DesktopShortcutStartupNotifyBehavior.cs" />
@ -109,6 +112,7 @@
<Compile Include="ObjectModels\RichTextMarkup\RichTextMarkupObjectModel.cs" />
<Compile Include="ObjectModels\RichTextMarkup\RichTextMarkupItemTag.cs" />
<Compile Include="ObjectModels\Security\Certificate\CertificateObjectModel.cs" />
<Compile Include="ObjectModels\Security\Key\RSA\RSAKeyObjectModel.cs" />
<Compile Include="ObjectModels\Shortcut\ShortcutObjectModel.cs" />
<Compile Include="ObjectModels\Solution\SolutionObjectModel.cs" />
<Compile Include="ObjectModels\Text\Formatted\FormattedTextFont.cs" />