培训考核三期,新版培训,网页版培训登录器
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

328 lines
9.8 KiB

#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.Globalization;
using System.Text;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1
{
/**
* Generalized time object.
*/
public class DerGeneralizedTime
: Asn1Object
{
private readonly string time;
/**
* return a generalized time from the passed in object
*
* @exception ArgumentException if the object cannot be converted.
*/
public static DerGeneralizedTime GetInstance(
object obj)
{
if (obj == null || obj is DerGeneralizedTime)
{
return (DerGeneralizedTime)obj;
}
throw new ArgumentException("illegal object in GetInstance: " + BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.GetTypeName(obj), "obj");
}
/**
* return a Generalized Time object from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicitly true if the object is meant to be explicitly
* tagged false otherwise.
* @exception ArgumentException if the tagged object cannot
* be converted.
*/
public static DerGeneralizedTime GetInstance(
Asn1TaggedObject obj,
bool isExplicit)
{
Asn1Object o = obj.GetObject();
if (isExplicit || o is DerGeneralizedTime)
{
return GetInstance(o);
}
return new DerGeneralizedTime(((Asn1OctetString)o).GetOctets());
}
/**
* The correct format for this is YYYYMMDDHHMMSS[.f]Z, or without the Z
* for local time, or Z+-HHMM on the end, for difference between local
* time and UTC time. The fractional second amount f must consist of at
* least one number with trailing zeroes removed.
*
* @param time the time string.
* @exception ArgumentException if string is an illegal format.
*/
public DerGeneralizedTime(
string time)
{
this.time = time;
try
{
ToDateTime();
}
catch (FormatException e)
{
throw new ArgumentException("invalid date string: " + e.Message);
}
}
/**
* base constructor from a local time object
*/
public DerGeneralizedTime(
DateTime time)
{
#if PORTABLE || NETFX_CORE
this.time = time.ToUniversalTime().ToString(@"yyyyMMddHHmmss\Z");
#else
this.time = time.ToString(@"yyyyMMddHHmmss\Z");
#endif
}
internal DerGeneralizedTime(
byte[] bytes)
{
//
// explicitly convert to characters
//
this.time = Strings.FromAsciiByteArray(bytes);
}
/**
* Return the time.
* @return The time string as it appeared in the encoded object.
*/
public string TimeString
{
get { return time; }
}
/**
* return the time - always in the form of
* YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm).
* <p>
* Normally in a certificate we would expect "Z" rather than "GMT",
* however adding the "GMT" means we can just use:
* <pre>
* dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
* </pre>
* To read in the time and Get a date which is compatible with our local
* time zone.</p>
*/
public string GetTime()
{
//
// standardise the format.
//
if (time[time.Length - 1] == 'Z')
{
return time.Substring(0, time.Length - 1) + "GMT+00:00";
}
else
{
int signPos = time.Length - 5;
char sign = time[signPos];
if (sign == '-' || sign == '+')
{
return time.Substring(0, signPos)
+ "GMT"
+ time.Substring(signPos, 3)
+ ":"
+ time.Substring(signPos + 3);
}
else
{
signPos = time.Length - 3;
sign = time[signPos];
if (sign == '-' || sign == '+')
{
return time.Substring(0, signPos)
+ "GMT"
+ time.Substring(signPos)
+ ":00";
}
}
}
return time + CalculateGmtOffset();
}
private string CalculateGmtOffset()
{
char sign = '+';
DateTime time = ToDateTime();
#if SILVERLIGHT || PORTABLE || NETFX_CORE
long offset = time.Ticks - time.ToUniversalTime().Ticks;
if (offset < 0)
{
sign = '-';
offset = -offset;
}
int hours = (int)(offset / TimeSpan.TicksPerHour);
int minutes = (int)(offset / TimeSpan.TicksPerMinute) % 60;
#else
// Note: GetUtcOffset incorporates Daylight Savings offset
TimeSpan offset = TimeZone.CurrentTimeZone.GetUtcOffset(time);
if (offset.CompareTo(TimeSpan.Zero) < 0)
{
sign = '-';
offset = offset.Duration();
}
int hours = offset.Hours;
int minutes = offset.Minutes;
#endif
return "GMT" + sign + Convert(hours) + ":" + Convert(minutes);
}
private static string Convert(
int time)
{
if (time < 10)
{
return "0" + time;
}
return time.ToString();
}
public DateTime ToDateTime()
{
string formatStr;
string d = time;
bool makeUniversal = false;
if (BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.EndsWith(d, "Z"))
{
if (HasFractionalSeconds)
{
int fCount = d.Length - d.IndexOf('.') - 2;
formatStr = @"yyyyMMddHHmmss." + FString(fCount) + @"\Z";
}
else
{
formatStr = @"yyyyMMddHHmmss\Z";
}
}
else if (time.IndexOf('-') > 0 || time.IndexOf('+') > 0)
{
d = GetTime();
makeUniversal = true;
if (HasFractionalSeconds)
{
int fCount = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.IndexOf(d, "GMT") - 1 - d.IndexOf('.');
formatStr = @"yyyyMMddHHmmss." + FString(fCount) + @"'GMT'zzz";
}
else
{
formatStr = @"yyyyMMddHHmmss'GMT'zzz";
}
}
else
{
if (HasFractionalSeconds)
{
int fCount = d.Length - 1 - d.IndexOf('.');
formatStr = @"yyyyMMddHHmmss." + FString(fCount);
}
else
{
formatStr = @"yyyyMMddHHmmss";
}
// TODO?
// dateF.setTimeZone(new SimpleTimeZone(0, TimeZone.getDefault().getID()));
}
return ParseDateString(d, formatStr, makeUniversal);
}
private string FString(
int count)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < count; ++i)
{
sb.Append('f');
}
return sb.ToString();
}
private DateTime ParseDateString(string s, string format, bool makeUniversal)
{
/*
* NOTE: DateTime.Kind and DateTimeStyles.AssumeUniversal not available in .NET 1.1
*/
DateTimeStyles style = DateTimeStyles.None;
if (BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.EndsWith(format, "Z"))
{
try
{
style = (DateTimeStyles)Enums.GetEnumValue(typeof(DateTimeStyles), "AssumeUniversal");
}
catch (Exception)
{
}
style |= DateTimeStyles.AdjustToUniversal;
}
DateTime dt = DateTime.ParseExact(s, format, DateTimeFormatInfo.InvariantInfo, style);
return makeUniversal ? dt.ToUniversalTime() : dt;
}
private bool HasFractionalSeconds
{
get { return time.IndexOf('.') == 14; }
}
private byte[] GetOctets()
{
return Strings.ToAsciiByteArray(time);
}
internal override int EncodedLength(bool withID)
{
return Asn1OutputStream.GetLengthOfEncodingDL(withID, time.Length);
}
internal override void Encode(Asn1OutputStream asn1Out, bool withID)
{
asn1Out.WriteEncodingDL(withID, Asn1Tags.GeneralizedTime, GetOctets());
}
protected override bool Asn1Equals(
Asn1Object asn1Object)
{
DerGeneralizedTime other = asn1Object as DerGeneralizedTime;
if (other == null)
return false;
return this.time.Equals(other.time);
}
protected override int Asn1GetHashCode()
{
return time.GetHashCode();
}
}
}
#pragma warning restore
#endif