Add project
Basic formatting applied. Unnecessary comments have been removed. Suspicious code is covered by TODO.
This commit is contained in:
@ -0,0 +1,201 @@
|
||||
using GostCryptography.Asn1.Gost.Gost_R3410;
|
||||
using GostCryptography.Properties;
|
||||
using System;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
|
||||
namespace GostCryptography.Gost_R3410
|
||||
{
|
||||
/// <summary>
|
||||
/// Базовый класс XML-сериализатора параметров ключа цифровой подписи ГОСТ Р 34.10
|
||||
/// </summary>
|
||||
/// <typeparam name="TKeyParams">Параметры ключа цифровой подписи ГОСТ Р 34.10</typeparam>
|
||||
public abstract class Gost_R3410_KeyExchangeXmlSerializer<TKeyParams> where TKeyParams : Gost_R3410_KeyExchangeParams
|
||||
{
|
||||
private const string OidPrefix = "urn:oid:";
|
||||
private const string PublicKeyParametersTag = "PublicKeyParameters";
|
||||
private const string PublicKeyParamSetTag = "publicKeyParamSet";
|
||||
private const string DigestParamSetTag = "digestParamSet";
|
||||
private const string EncryptionParamSetTag = "encryptionParamSet";
|
||||
private const string PublicKeyTag = "PublicKey";
|
||||
private const string PrivateKeyTag = "PrivateKey";
|
||||
|
||||
private readonly string _keyValueTag;
|
||||
|
||||
/// <summary>
|
||||
/// Создает новый экземпляр данного класса
|
||||
/// </summary>
|
||||
/// <param name="keyValueTag">Имя тега с информацией о параметрах ключа</param>
|
||||
protected Gost_R3410_KeyExchangeXmlSerializer(string keyValueTag)
|
||||
{
|
||||
_keyValueTag = keyValueTag;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Возвращает XML с параметрами ключа
|
||||
/// </summary>
|
||||
public string Serialize(TKeyParams parameters)
|
||||
{
|
||||
var builder = new StringBuilder().AppendFormat("<{0}>", _keyValueTag);
|
||||
|
||||
if ((parameters.DigestParamSet != null) || (parameters.EncryptionParamSet != null) || (parameters.PublicKeyParamSet != null))
|
||||
{
|
||||
builder.AppendFormat("<{0}>", PublicKeyParametersTag);
|
||||
builder.AppendFormat("<{0}>{1}{2}</{0}>", PublicKeyParamSetTag, OidPrefix, parameters.PublicKeyParamSet);
|
||||
builder.AppendFormat("<{0}>{1}{2}</{0}>", DigestParamSetTag, OidPrefix, parameters.DigestParamSet);
|
||||
|
||||
if (parameters.EncryptionParamSet != null)
|
||||
{
|
||||
builder.AppendFormat("<{0}>{1}{2}</{0}>", EncryptionParamSetTag, OidPrefix, parameters.EncryptionParamSet);
|
||||
}
|
||||
|
||||
builder.AppendFormat("</{0}>", PublicKeyParametersTag);
|
||||
}
|
||||
|
||||
builder.AppendFormat("<{0}>{1}</{0}>", PublicKeyTag, Convert.ToBase64String(parameters.PublicKey));
|
||||
|
||||
if (parameters.PrivateKey != null)
|
||||
{
|
||||
builder.AppendFormat("<{0}>{1}</{0}>", PrivateKeyTag, Convert.ToBase64String(parameters.PublicKey));
|
||||
}
|
||||
|
||||
builder.AppendFormat("</{0}>", _keyValueTag);
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Возвращает параметры ключа на основе XML
|
||||
/// </summary>
|
||||
public TKeyParams Deserialize(string keyParametersXml, TKeyParams parameters)
|
||||
{
|
||||
if (string.IsNullOrEmpty(keyParametersXml))
|
||||
{
|
||||
throw ExceptionUtility.ArgumentNull(nameof(keyParametersXml));
|
||||
}
|
||||
|
||||
var keyValue = SecurityElement.FromString(keyParametersXml);
|
||||
|
||||
if (keyValue == null)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.InvalidFromXmlString, _keyValueTag);
|
||||
}
|
||||
|
||||
keyValue = SelectChildElement(keyValue, _keyValueTag) ?? keyValue;
|
||||
|
||||
var publicKeyParameters = SelectChildElement(keyValue, PublicKeyParametersTag);
|
||||
|
||||
if (publicKeyParameters != null)
|
||||
{
|
||||
var publicKeyParamSet = RemoveWhiteSpaces(SelectChildElementText(publicKeyParameters, PublicKeyParamSetTag, false));
|
||||
|
||||
if (!publicKeyParamSet.StartsWith(OidPrefix, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.InvalidFromXmlString, PublicKeyParamSetTag);
|
||||
}
|
||||
|
||||
parameters.PublicKeyParamSet = publicKeyParamSet.Substring(OidPrefix.Length);
|
||||
|
||||
var digestParamSet = RemoveWhiteSpaces(SelectChildElementText(publicKeyParameters, DigestParamSetTag, false));
|
||||
|
||||
if (!digestParamSet.StartsWith(OidPrefix, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.InvalidFromXmlString, DigestParamSetTag);
|
||||
}
|
||||
|
||||
parameters.DigestParamSet = digestParamSet.Substring(OidPrefix.Length);
|
||||
|
||||
var encryptionParamSet = SelectChildElementText(publicKeyParameters, EncryptionParamSetTag, true);
|
||||
|
||||
if (!string.IsNullOrEmpty(encryptionParamSet))
|
||||
{
|
||||
encryptionParamSet = RemoveWhiteSpaces(encryptionParamSet);
|
||||
|
||||
if (!encryptionParamSet.StartsWith(OidPrefix, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.InvalidFromXmlString, EncryptionParamSetTag);
|
||||
}
|
||||
|
||||
parameters.EncryptionParamSet = encryptionParamSet.Substring(OidPrefix.Length);
|
||||
}
|
||||
}
|
||||
|
||||
var publicKey = SelectChildElementText(keyValue, PublicKeyTag, false);
|
||||
parameters.PublicKey = Convert.FromBase64String(RemoveWhiteSpaces(publicKey));
|
||||
|
||||
var privateKey = SelectChildElementText(keyValue, PrivateKeyTag, true);
|
||||
|
||||
if (privateKey != null)
|
||||
{
|
||||
parameters.PrivateKey = Convert.FromBase64String(RemoveWhiteSpaces(privateKey));
|
||||
}
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
private static string SelectChildElementText(SecurityElement element, string childName, bool canNull)
|
||||
{
|
||||
string text = null;
|
||||
|
||||
var child = SelectChildElement(element, childName);
|
||||
|
||||
if (child != null && (child.Children == null || child.Children.Count == 0))
|
||||
{
|
||||
text = child.Text;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(text) && !canNull)
|
||||
{
|
||||
throw ExceptionUtility.CryptographicException(Resources.InvalidFromXmlString, childName);
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
private static SecurityElement SelectChildElement(SecurityElement element, string childName)
|
||||
{
|
||||
var children = element.Children;
|
||||
|
||||
if (children != null)
|
||||
{
|
||||
foreach (SecurityElement child in children)
|
||||
{
|
||||
if (string.Equals(child.Tag, childName, StringComparison.OrdinalIgnoreCase)
|
||||
|| child.Tag.EndsWith(":" + childName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string RemoveWhiteSpaces(string value)
|
||||
{
|
||||
var length = value.Length;
|
||||
|
||||
var countWhiteSpace = 0;
|
||||
|
||||
for (var i = 0; i < length; ++i)
|
||||
{
|
||||
if (char.IsWhiteSpace(value[i]))
|
||||
{
|
||||
++countWhiteSpace;
|
||||
}
|
||||
}
|
||||
|
||||
var valueWithoutWhiteSpace = new char[length - countWhiteSpace];
|
||||
|
||||
for (int i = 0, j = 0; i < length; ++i)
|
||||
{
|
||||
if (!char.IsWhiteSpace(value[i]))
|
||||
{
|
||||
valueWithoutWhiteSpace[j++] = value[i];
|
||||
}
|
||||
}
|
||||
|
||||
return new string(valueWithoutWhiteSpace);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user