101 lines
3.1 KiB
C#
101 lines
3.1 KiB
C#
using GostCryptography.Asn1.Ber;
|
|
using GostCryptography.Properties;
|
|
using System;
|
|
|
|
namespace GostCryptography.Asn1.Gost.PublicKey
|
|
{
|
|
public sealed class AlgorithmIdentifier : Asn1Type
|
|
{
|
|
public AlgorithmIdentifier()
|
|
{
|
|
}
|
|
|
|
public AlgorithmIdentifier(Asn1ObjectIdentifier algorithm, Asn1OpenType parameters)
|
|
{
|
|
Algorithm = algorithm;
|
|
Parameters = parameters;
|
|
}
|
|
|
|
public Asn1ObjectIdentifier Algorithm { get; private set; }
|
|
|
|
public Asn1Type Parameters { get; private set; }
|
|
|
|
public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength)
|
|
{
|
|
var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength;
|
|
|
|
Algorithm = null;
|
|
Parameters = null;
|
|
|
|
var context = new Asn1BerDecodeContext(buffer, elemLength);
|
|
var parsedLen = new IntHolder();
|
|
|
|
if (!context.MatchElemTag(0, 0, ObjectIdentifierTypeCode, parsedLen, false))
|
|
{
|
|
throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount);
|
|
}
|
|
|
|
Algorithm = new Asn1ObjectIdentifier();
|
|
Algorithm.Decode(buffer, true, parsedLen.Value);
|
|
|
|
if (!context.Expired())
|
|
{
|
|
Parameters = new Asn1OpenType();
|
|
Parameters.Decode(buffer, true, 0);
|
|
}
|
|
|
|
CheckAlg(true);
|
|
}
|
|
|
|
public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging)
|
|
{
|
|
var len = 0;
|
|
CheckAlg(false);
|
|
|
|
if (Parameters != null)
|
|
{
|
|
len += Parameters.Encode(buffer, true);
|
|
}
|
|
|
|
len += Algorithm.Encode(buffer, true);
|
|
|
|
if (explicitTagging)
|
|
{
|
|
len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len);
|
|
}
|
|
|
|
return len;
|
|
}
|
|
|
|
private void CheckAlg(bool decode)
|
|
{
|
|
AlgorithmId algorithmId = null;
|
|
|
|
foreach (var alg in PkiConstants.SupportedAlgorithms)
|
|
{
|
|
if (alg.Id.Equals(Algorithm))
|
|
{
|
|
algorithmId = alg;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((algorithmId != null) && ((decode && (Parameters != null)) && (algorithmId.Type != null)))
|
|
{
|
|
try
|
|
{
|
|
var buffer = new Asn1BerDecodeBuffer(((Asn1OpenType)Parameters).Value);
|
|
Parameters = (Asn1Type)Activator.CreateInstance(algorithmId.Type.GetType());
|
|
Parameters.Decode(buffer, true, 0);
|
|
buffer.InvokeEndElement("parameters", -1);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
Asn1Util.WriteStackTrace(exception, Console.Error);
|
|
throw ExceptionUtility.CryptographicException(Resources.Asn1TableConstraint);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|