diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-08-11 12:41:05 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-08-11 12:41:05 +0700 |
commit | 2447cea7296abf3b77207eeeb39dc75ae2a73a4e (patch) | |
tree | 2e01b1b243d0b9a506934765632685931ebf40aa /crypto/src/asn1/DerGeneralizedTime.cs | |
parent | Add note for future Arm implementation (diff) | |
download | BouncyCastle.NET-ed25519-2447cea7296abf3b77207eeeb39dc75ae2a73a4e.tar.xz |
GeneralizedTime improvements
Diffstat (limited to 'crypto/src/asn1/DerGeneralizedTime.cs')
-rw-r--r-- | crypto/src/asn1/DerGeneralizedTime.cs | 94 |
1 files changed, 71 insertions, 23 deletions
diff --git a/crypto/src/asn1/DerGeneralizedTime.cs b/crypto/src/asn1/DerGeneralizedTime.cs index 16774cb02..22dc04912 100644 --- a/crypto/src/asn1/DerGeneralizedTime.cs +++ b/crypto/src/asn1/DerGeneralizedTime.cs @@ -139,32 +139,28 @@ namespace Org.BouncyCastle.Asn1 // standardise the format. // if (time[time.Length - 1] == 'Z') - { return time.Substring(0, time.Length - 1) + "GMT+00:00"; + + 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 { - int signPos = time.Length - 5; - char sign = time[signPos]; + signPos = time.Length - 3; + 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"; - } + + time.Substring(signPos) + + ":00"; } } @@ -212,10 +208,18 @@ namespace Org.BouncyCastle.Asn1 int fCount = d.Length - d.IndexOf('.') - 2; formatStr = @"yyyyMMddHHmmss." + FString(fCount) + @"\Z"; } - else + else if (HasSeconds) { formatStr = @"yyyyMMddHHmmss\Z"; } + else if (HasMinutes) + { + formatStr = @"yyyyMMddHHmm\Z"; + } + else + { + formatStr = @"yyyyMMddHH\Z"; + } } else if (time.IndexOf('-') > 0 || time.IndexOf('+') > 0) { @@ -239,10 +243,18 @@ namespace Org.BouncyCastle.Asn1 int fCount = d.Length - 1 - d.IndexOf('.'); formatStr = @"yyyyMMddHHmmss." + FString(fCount); } - else + else if (HasSeconds) { formatStr = @"yyyyMMddHHmmss"; } + else if (HasMinutes) + { + formatStr = @"yyyyMMddHHmm"; + } + else + { + formatStr = @"yyyyMMddHH"; + } // TODO? // dateF.setTimeZone(new SimpleTimeZone(0, TimeZone.getDefault().getID())); @@ -291,19 +303,55 @@ namespace Org.BouncyCastle.Asn1 get { return time.IndexOf('.') == 14; } } - private byte[] GetOctets() + private bool HasSeconds => IsDigit(12) && IsDigit(13); + + private bool HasMinutes => IsDigit(10) && IsDigit(11); + + private bool IsDigit(int pos) + { + return time.Length > pos && char.IsDigit(time[pos]); + } + + private byte[] GetOctets(int encoding) { + if (Asn1OutputStream.EncodingDer == encoding && time[time.Length - 1] == 'Z') + { + if (!HasMinutes) + return Strings.ToAsciiByteArray(time.Insert(time.Length - 1, "0000")); + if (!HasSeconds) + return Strings.ToAsciiByteArray(time.Insert(time.Length - 1, "00")); + + if (HasFractionalSeconds) + { + int ind = time.Length - 2; + while (ind > 0 && time[ind] == '0') + { + --ind; + } + + if (time[ind] != '.') + { + ++ind; + } + + if (ind != time.Length - 1) + { + return Strings.ToAsciiByteArray(time.Remove(ind, time.Length - 1 - ind)); + } + } + } + return Strings.ToAsciiByteArray(time); } internal override IAsn1Encoding GetEncoding(int encoding) { - return new PrimitiveEncoding(Asn1Tags.Universal, Asn1Tags.GeneralizedTime, GetOctets()); + return new PrimitiveEncoding(Asn1Tags.Universal, Asn1Tags.GeneralizedTime, GetOctets(encoding)); } internal override IAsn1Encoding GetEncodingImplicit(int encoding, int tagClass, int tagNo) { - return new PrimitiveEncoding(tagClass, tagNo, GetOctets()); + return new PrimitiveEncoding(tagClass, tagNo, GetOctets(encoding)); } protected override bool Asn1Equals(Asn1Object asn1Object) |