Files
hcs/Hcs.ClientNet/GostCryptography/Asn1/Ber/Asn1Time.cs

555 lines
14 KiB
C#

using GostCryptography.Properties;
using System;
using System.Text;
namespace GostCryptography.Asn1.Ber
{
[Serializable]
public abstract class Asn1Time : Asn18BitCharString, IComparable
{
public const int January = 1;
public const int February = 2;
public const int March = 3;
public const int April = 4;
public const int May = 5;
public const int June = 6;
public const int July = 7;
public const int August = 8;
public const int September = 9;
public const int October = 10;
public const int November = 11;
public const int December = 12;
public static readonly short[] DaysInMonth = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
public Asn1Time(short typeCode, bool useDerRules)
: base(typeCode)
{
DerRules = useDerRules;
Init();
}
public Asn1Time(string data, short typeCode, bool useDerRules)
: base(data, typeCode)
{
DerRules = useDerRules;
Init();
}
[NonSerialized]
protected bool Parsed;
[NonSerialized]
protected bool DerRules;
[NonSerialized]
protected int DiffHourValue;
public virtual int DiffHour
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return DiffHourValue;
}
set
{
if ((value < -12) || (value > 12))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffHourValue, value);
}
SafeParseString();
DiffHourValue = value;
CompileString();
}
}
[NonSerialized]
protected int DiffMinValue;
public virtual int DiffMinute
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return DiffMinValue;
}
}
[NonSerialized]
protected string SecFraction;
public virtual string Fraction
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return SecFraction;
}
set
{
SafeParseString();
SecFraction = value;
CompileString();
}
}
[NonSerialized]
protected int YearValue;
public virtual int Year
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return YearValue;
}
set
{
if (value < 0)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidYearValue, value);
}
if (!CheckDate(DayValue, MonthValue, value))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidYearValueForDayAndMonth, value, DayValue, MonthValue);
}
SafeParseString();
YearValue = value;
CompileString();
}
}
[NonSerialized]
protected int MonthValue;
public virtual int Month
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return MonthValue;
}
set
{
if ((value < 1) || (value > 12))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMonthValue, value);
}
if (!CheckDate(DayValue, value, YearValue))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMonthValueForDayAndYear, value, DayValue, YearValue);
}
SafeParseString();
MonthValue = value;
CompileString();
}
}
[NonSerialized]
protected int DayValue;
public virtual int Day
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return DayValue;
}
set
{
if (((value < 1) || (value > 31)) || !CheckDate(value, MonthValue, YearValue))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDayValueForMonthAndYear, value, MonthValue, YearValue);
}
SafeParseString();
DayValue = value;
CompileString();
}
}
[NonSerialized]
protected int HourValue;
public virtual int Hour
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return HourValue;
}
set
{
if ((value < 0) || (value > 23))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidHourValue, value);
}
SafeParseString();
HourValue = value;
CompileString();
}
}
[NonSerialized]
protected int MinuteValue;
public virtual int Minute
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return MinuteValue;
}
set
{
if ((value < 0) || (value > 59))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidMinuteValue, value);
}
SafeParseString();
MinuteValue = value;
CompileString();
}
}
[NonSerialized]
protected int SecondValue;
public virtual int Second
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return SecondValue;
}
set
{
if ((value < 0) || (value > 59))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidSecondValue, value);
}
SafeParseString();
SecondValue = value;
CompileString();
}
}
[NonSerialized]
protected bool UtcFlag;
public virtual bool Utc
{
get
{
if (!Parsed)
{
ParseString(Value);
}
return UtcFlag;
}
set
{
if (!DerRules)
{
SafeParseString();
UtcFlag = value;
CompileString();
}
}
}
public virtual int CompareTo(object other)
{
if (other is DateTime)
{
var time2 = (DateTime)other;
return (int)(GetTime().Ticks - time2.Ticks);
}
return (int)(GetTime().Ticks - ((Asn1Time)other).GetTime().Ticks);
}
protected static char CharAt(string s, int index)
{
if (index >= s.Length)
{
return '\0';
}
return s[index];
}
private static bool CheckDate(int day, int month, int year)
{
if ((day <= 0) || (month <= 0))
{
return true;
}
if ((year >= 0) && (month > 0))
{
int num = DaysInMonth[month];
if (((month == 2) && ((year % 4) == 0)) && (((year % 100) != 0) || ((year % 400) == 0)))
{
num++;
}
if ((day >= 1) && (day <= num))
{
return true;
}
}
else if (month > 0)
{
if (day <= DaysInMonth[month])
{
return true;
}
if ((month == 2) && (day <= (DaysInMonth[month] + 1)))
{
return true;
}
}
return false;
}
public virtual void Clear()
{
YearValue = MonthValue = DayValue = HourValue = -1;
MinuteValue = SecondValue = DiffHourValue = DiffMinValue = 0;
UtcFlag = DerRules;
Parsed = true;
SecFraction = "";
Value = "";
}
protected abstract bool CompileString();
protected override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength, Asn1Tag tag)
{
Parsed = false;
base.Decode(buffer, explicitTagging, implicitLength, tag);
DerRules = buffer is Asn1DerDecodeBuffer;
}
protected override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging, Asn1Tag tag)
{
SafeParseString();
var flag = buffer is Asn1DerEncodeBuffer;
if (DerRules != flag)
{
DerRules = flag;
if (!CompileString())
{
throw ExceptionUtility.CryptographicException(Resources.Asn1TimeStringCouldNotBeGenerated);
}
}
return base.Encode(buffer, explicitTagging, tag);
}
public virtual void Encode(Asn1BerOutputStream outs, bool explicitTagging, Asn1Tag tag)
{
SafeParseString();
outs.EncodeCharString(Value, explicitTagging, tag);
}
public override bool Equals(object value)
{
if (value is Asn1Time)
{
return GetTime().Equals(((Asn1Time)value).GetTime());
}
return ((value is DateTime) && GetTime().Equals((DateTime)value));
}
public virtual int GetDiff()
{
if (!Parsed)
{
ParseString(Value);
}
return ((DiffHourValue * 60) + DiffMinValue);
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public virtual DateTime GetTime()
{
if (!string.IsNullOrEmpty(SecFraction))
{
return new DateTime(YearValue, MonthValue, DayValue, HourValue, MinuteValue, SecondValue, int.Parse(SecFraction));
}
return new DateTime(YearValue, MonthValue, DayValue, HourValue, MinuteValue, SecondValue);
}
protected virtual void Init()
{
YearValue = MonthValue = DayValue = HourValue = -1;
MinuteValue = SecondValue = 0;
DiffHourValue = DiffMinValue = 0;
UtcFlag = DerRules;
SecFraction = "";
}
protected static int ParseInt(string str, IntHolder off, int len)
{
if ((off.Value + len) > str.Length)
{
throw ExceptionUtility.ArgumentOutOfRange("off");
}
var mValue = off.Value;
off.Value += len;
return int.Parse(str.Substring(mValue, len));
}
public abstract void ParseString(string data);
protected virtual void PutInteger(int width, int value)
{
PutInteger(StringBuffer, width, value);
}
public static void PutInteger(StringBuilder data, int width, int value)
{
var str = Convert.ToString(value);
var length = str.Length;
if (length < width)
{
for (var i = length; i < width; i++)
{
data.Append('0');
}
}
else if (length > width)
{
str = str.Substring(length - width);
}
data.Append(str);
}
protected virtual void SafeParseString()
{
try
{
if (!Parsed)
{
ParseString(Value);
}
}
catch (Exception)
{
}
}
public virtual void SetDiff(int inMinutes)
{
if (Math.Abs(inMinutes) > 720)
{
throw ExceptionUtility.CryptographicException(Resources.InvalidDiffValue, inMinutes);
}
SafeParseString();
DiffHourValue = inMinutes / 60;
DiffMinValue = inMinutes % 60;
CompileString();
}
public virtual void SetDiff(int dhour, int dminute)
{
if ((dhour < -12) || (dhour > 12))
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffHourValue, dhour);
}
if (Math.Abs(dminute) > 59)
{
throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidDiffMinuteValue, dminute);
}
SafeParseString();
DiffHourValue = dhour;
if (dhour < 0)
{
DiffMinValue = -Math.Abs(dminute);
}
else
{
DiffMinValue = Math.Abs(dminute);
}
CompileString();
}
public virtual void SetTime(DateTime time)
{
Clear();
YearValue = time.Year;
MonthValue = time.Month;
DayValue = time.Day;
HourValue = time.Hour;
MinuteValue = time.Minute;
SecondValue = time.Second;
SecFraction = Convert.ToString(time.Millisecond);
DiffHourValue = DiffMinValue = 0;
UtcFlag = DerRules;
CompileString();
}
}
}