diff options
Diffstat (limited to 'crypto/src/asn1')
92 files changed, 3453 insertions, 2124 deletions
diff --git a/crypto/src/asn1/Asn1EncodableVector.cs b/crypto/src/asn1/Asn1EncodableVector.cs index f50eb6f98..bf8d324ad 100644 --- a/crypto/src/asn1/Asn1EncodableVector.cs +++ b/crypto/src/asn1/Asn1EncodableVector.cs @@ -133,6 +133,14 @@ namespace Org.BouncyCastle.Asn1 } } + public void AddOptionalTagged(bool isExplicit, int tagClass, int tagNo, Asn1Encodable obj) + { + if (null != obj) + { + Add(new DerTaggedObject(isExplicit, tagClass, tagNo, obj)); + } + } + public void AddAll(Asn1EncodableVector other) { if (null == other) diff --git a/crypto/src/asn1/Asn1GeneralizedTime.cs b/crypto/src/asn1/Asn1GeneralizedTime.cs new file mode 100644 index 000000000..139384c1a --- /dev/null +++ b/crypto/src/asn1/Asn1GeneralizedTime.cs @@ -0,0 +1,438 @@ +using System; +using System.Globalization; +using System.IO; +using System.Text; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * Base class representing the ASN.1 GeneralizedTime type. + * <p> + * The main difference between these and UTC time is a 4 digit year. + * </p><p> + * One second resolution date+time on UTC timezone (Z) + * with 4 digit year (valid from 0001 to 9999). + * </p><p> + * Timestamp format is: yyyymmddHHMMSS'Z' + * </p><p> + * <h2>X.690</h2> + * This is what is called "restricted string", + * and it uses ASCII characters to encode digits and supplemental data. + * + * <h3>11: Restrictions on BER employed by both CER and DER</h3> + * <h4>11.7 GeneralizedTime </h4> + * </p><p> + * <b>11.7.1</b> The encoding shall terminate with a "Z", + * as described in the ITU-T Rec. X.680 | ISO/IEC 8824-1 clause on + * GeneralizedTime. + * </p><p> + * <b>11.7.2</b> The seconds element shall always be present. + * </p><p> + * <b>11.7.3</b> The fractional-seconds elements, if present, + * shall omit all trailing zeros; if the elements correspond to 0, + * they shall be wholly omitted, and the decimal point element also + * shall be omitted. + * </p> + */ + public class Asn1GeneralizedTime + : Asn1Object + { + internal class Meta : Asn1UniversalType + { + internal static readonly Asn1UniversalType Instance = new Meta(); + + private Meta() : base(typeof(Asn1GeneralizedTime), Asn1Tags.GeneralizedTime) { } + + internal override Asn1Object FromImplicitPrimitive(DerOctetString octetString) + { + return CreatePrimitive(octetString.GetOctets()); + } + } + + public static Asn1GeneralizedTime GetInstance(object obj) + { + if (obj == null) + return null; + + if (obj is Asn1GeneralizedTime asn1GeneralizedTime) + return asn1GeneralizedTime; + + if (obj is IAsn1Convertible asn1Convertible) + { + Asn1Object asn1Object = asn1Convertible.ToAsn1Object(); + if (asn1Object is Asn1GeneralizedTime converted) + return converted; + } + else if (obj is byte[] bytes) + { + try + { + return (Asn1GeneralizedTime)Meta.Instance.FromByteArray(bytes); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct generalized time from byte[]: " + e.Message); + } + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), nameof(obj)); + } + + public static Asn1GeneralizedTime GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return (Asn1GeneralizedTime)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit); + } + + internal readonly byte[] m_contents; + + public Asn1GeneralizedTime(string time) + { + m_contents = Strings.ToByteArray(time); + + try + { + ToDateTime(); + } + catch (FormatException e) + { + throw new ArgumentException("invalid date string: " + e.Message); + } + } + + public Asn1GeneralizedTime(DateTime time) + { + DateTime utc = time.ToUniversalTime(); + var formatStr = @"yyyyMMddHHmmss\Z"; + var formatProvider = DateTimeFormatInfo.InvariantInfo; + string utcString = utc.ToString(formatStr, formatProvider); + m_contents = Strings.ToByteArray(utcString); + } + + // TODO Custom locale constructor? + //public Asn1GeneralizedTime(DateTime time, Locale locale) + //{ + // SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss\Z", locale); + + // dateF.setTimeZone(new SimpleTimeZone(0, "Z")); + + // this.contents = Strings.toByteArray(dateF.format(time)); + //} + + internal Asn1GeneralizedTime(byte[] bytes) + { + if (bytes == null) + throw new ArgumentNullException(nameof(bytes)); + if (bytes.Length < 4) + throw new ArgumentException("GeneralizedTime string too short", nameof(bytes)); + + m_contents = bytes; + + if (!(IsDigit(0) && IsDigit(1) && IsDigit(2) && IsDigit(3))) + throw new ArgumentException("illegal characters in GeneralizedTime string", nameof(bytes)); + } + + public string TimeString => Strings.FromByteArray(m_contents); + + public string GetTime() + { + string stime = Strings.FromByteArray(m_contents); + + // + // standardise the format. + // + if (stime[stime.Length - 1] == 'Z') + return stime.Substring(0, stime.Length - 1) + "GMT+00:00"; + + int signPos = stime.Length - 6; + char sign = stime[signPos]; + if ((sign == '-' || sign == '+') && stime.IndexOf("GMT") == signPos - 3) + { + // already a GMT string! + return stime; + } + + signPos = stime.Length - 5; + sign = stime[signPos]; + if (sign == '-' || sign == '+') + { + return stime.Substring(0, signPos) + + "GMT" + + stime.Substring(signPos, 3) + + ":" + + stime.Substring(signPos + 3); + } + + signPos = stime.Length - 3; + sign = stime[signPos]; + if (sign == '-' || sign == '+') + { + return stime.Substring(0, signPos) + + "GMT" + + stime.Substring(signPos) + + ":00"; + } + + return stime + CalculateGmtOffset(stime); + } + + private string CalculateGmtOffset(string stime) + { + TimeZoneInfo timeZone = TimeZoneInfo.Local; + TimeSpan offset = timeZone.BaseUtcOffset; + + string sign = "+"; + if (offset.CompareTo(TimeSpan.Zero) < 0) + { + sign = "-"; + offset = offset.Duration(); + } + + int hours = offset.Hours; + int minutes = offset.Minutes; + + try + { + if (timeZone.SupportsDaylightSavingTime) + { + string d = stime + "GMT" + sign + Convert(hours) + ":" + Convert(minutes); + string formatStr = CalculateGmtFormatString(d); + + DateTime dateTime = ParseDateString(d, formatStr, makeUniversal: true); + + if (timeZone.IsDaylightSavingTime(dateTime)) + { + hours += sign.Equals("+") ? 1 : -1; + } + } + } + catch (Exception) + { + // we'll do our best and ignore daylight savings + } + + return "GMT" + sign + Convert(hours) + ":" + Convert(minutes); + } + + private string CalculateGmtFormatString(string d) + { + if (HasFractionalSeconds()) + { + int fCount = Platform.IndexOf(d, "GMT") - 1 - d.IndexOf('.'); + return @"yyyyMMddHHmmss." + FString(fCount) + @"'GMT'zzz"; + } + + if (HasSeconds()) + return @"yyyyMMddHHmmss'GMT'zzz"; + + if (HasMinutes()) + return @"yyyyMMddHHmm'GMT'zzz"; + + return @"yyyyMMddHH'GMT'zzz"; + } + + private string Convert(int time) + { + if (time < 10) + return "0" + time; + + return time.ToString(); + } + + public DateTime ToDateTime() + { + string formatStr; + string stime = Strings.FromByteArray(m_contents); + string d = stime; + bool makeUniversal = false; + + if (Platform.EndsWith(stime, "Z")) + { + if (HasFractionalSeconds()) + { + int fCount = d.Length - d.IndexOf('.') - 2; + formatStr = @"yyyyMMddHHmmss." + FString(fCount) + @"\Z"; + } + else if (HasSeconds()) + { + formatStr = @"yyyyMMddHHmmss\Z"; + } + else if (HasMinutes()) + { + formatStr = @"yyyyMMddHHmm\Z"; + } + else + { + formatStr = @"yyyyMMddHH\Z"; + } + } + else if (stime.IndexOf('-') > 0 || stime.IndexOf('+') > 0) + { + d = GetTime(); + formatStr = CalculateGmtFormatString(d); + makeUniversal = true; + } + else + { + if (HasFractionalSeconds()) + { + int fCount = d.Length - 1 - d.IndexOf('.'); + formatStr = @"yyyyMMddHHmmss." + FString(fCount); + } + else if (HasSeconds()) + { + formatStr = @"yyyyMMddHHmmss"; + } + else if (HasMinutes()) + { + formatStr = @"yyyyMMddHHmm"; + } + else + { + formatStr = @"yyyyMMddHH"; + } + } + + // TODO Epoch adjustment? + //return DateUtil.epochAdjust(dateF.parse(d)); + return ParseDateString(d, formatStr, makeUniversal); + } + + protected bool HasFractionalSeconds() + { + return m_contents.Length > 14 && m_contents[14] == '.'; + } + + protected bool HasSeconds() + { + return IsDigit(12) && IsDigit(13); + } + + protected bool HasMinutes() + { + return IsDigit(10) && IsDigit(11); + } + + private bool IsDigit(int pos) + { + return m_contents.Length > pos && m_contents[pos] >= '0' && m_contents[pos] <= '9'; + } + + internal override IAsn1Encoding GetEncoding(int encoding) + { + if (Asn1OutputStream.EncodingDer == encoding) + return new PrimitiveEncoding(Asn1Tags.Universal, Asn1Tags.GeneralizedTime, GetDerTime()); + + return new PrimitiveEncoding(Asn1Tags.Universal, Asn1Tags.GeneralizedTime, m_contents); + } + + internal override IAsn1Encoding GetEncodingImplicit(int encoding, int tagClass, int tagNo) + { + if (Asn1OutputStream.EncodingDer == encoding) + return new PrimitiveEncoding(tagClass, tagNo, GetDerTime()); + + return new PrimitiveEncoding(tagClass, tagNo, m_contents); + } + + protected override bool Asn1Equals(Asn1Object asn1Object) + { + if (!(asn1Object is Asn1GeneralizedTime that)) + return false; + + return Arrays.AreEqual(m_contents, that.m_contents); + } + + protected override int Asn1GetHashCode() + { + return Arrays.GetHashCode(m_contents); + } + + internal static Asn1GeneralizedTime CreatePrimitive(byte[] contents) + { + return new Asn1GeneralizedTime(contents); + } + + internal byte[] GetDerTime() + { + if (m_contents[m_contents.Length - 1] != 'Z') + { + return m_contents; // TODO: is there a better way? + } + + if (!HasMinutes()) + { + byte[] derTime = new byte[m_contents.Length + 4]; + + Array.Copy(m_contents, 0, derTime, 0, m_contents.Length - 1); + Array.Copy(Strings.ToByteArray("0000Z"), 0, derTime, m_contents.Length - 1, 5); + + return derTime; + } + else if (!HasSeconds()) + { + byte[] derTime = new byte[m_contents.Length + 2]; + + Array.Copy(m_contents, 0, derTime, 0, m_contents.Length - 1); + Array.Copy(Strings.ToByteArray("00Z"), 0, derTime, m_contents.Length - 1, 3); + + return derTime; + } + else if (HasFractionalSeconds()) + { + int ind = m_contents.Length - 2; + while (ind > 0 && m_contents[ind] == '0') + { + ind--; + } + + if (m_contents[ind] == '.') + { + byte[] derTime = new byte[ind + 1]; + + Array.Copy(m_contents, 0, derTime, 0, ind); + derTime[ind] = (byte)'Z'; + + return derTime; + } + else + { + byte[] derTime = new byte[ind + 2]; + + Array.Copy(m_contents, 0, derTime, 0, ind + 1); + derTime[ind + 1] = (byte)'Z'; + + return derTime; + } + } + else + { + return m_contents; + } + } + + private static string FString(int count) + { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < count; ++i) + { + sb.Append('f'); + } + return sb.ToString(); + } + + private static DateTime ParseDateString(string s, string format, bool makeUniversal) + { + DateTimeStyles dateTimeStyles = DateTimeStyles.None; + if (Platform.EndsWith(format, "Z")) + { + dateTimeStyles |= DateTimeStyles.AdjustToUniversal; + dateTimeStyles |= DateTimeStyles.AssumeUniversal; + } + + DateTime dt = DateTime.ParseExact(s, format, DateTimeFormatInfo.InvariantInfo, dateTimeStyles); + + return makeUniversal ? dt.ToUniversalTime() : dt; + } + } +} diff --git a/crypto/src/asn1/Asn1InputStream.cs b/crypto/src/asn1/Asn1InputStream.cs index aa91cdf62..0e772010f 100644 --- a/crypto/src/asn1/Asn1InputStream.cs +++ b/crypto/src/asn1/Asn1InputStream.cs @@ -426,7 +426,7 @@ namespace Org.BouncyCastle.Asn1 case Asn1Tags.BitString: return DerBitString.CreatePrimitive(bytes); case Asn1Tags.GeneralizedTime: - return DerGeneralizedTime.CreatePrimitive(bytes); + return Asn1GeneralizedTime.CreatePrimitive(bytes); case Asn1Tags.GeneralString: return DerGeneralString.CreatePrimitive(bytes); case Asn1Tags.GraphicString: @@ -452,7 +452,7 @@ namespace Org.BouncyCastle.Asn1 case Asn1Tags.UniversalString: return DerUniversalString.CreatePrimitive(bytes); case Asn1Tags.UtcTime: - return DerUtcTime.CreatePrimitive(bytes); + return Asn1UtcTime.CreatePrimitive(bytes); case Asn1Tags.Utf8String: return DerUtf8String.CreatePrimitive(bytes); case Asn1Tags.VideotexString: diff --git a/crypto/src/asn1/Asn1OutputStream.cs b/crypto/src/asn1/Asn1OutputStream.cs index 1a69d7c2c..163e3848c 100644 --- a/crypto/src/asn1/Asn1OutputStream.cs +++ b/crypto/src/asn1/Asn1OutputStream.cs @@ -1,5 +1,10 @@ using System; using System.IO; +using System.Diagnostics; +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER +using System.Buffers.Binary; +using System.Numerics; +#endif using Org.BouncyCastle.Utilities.IO; @@ -73,10 +78,18 @@ namespace Org.BouncyCastle.Asn1 { if (dl < 128) { + Debug.Assert(dl >= 0); WriteByte((byte)dl); return; } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + Span<byte> encoding = stackalloc byte[5]; + BinaryPrimitives.WriteUInt32BigEndian(encoding[1..], (uint)dl); + int leadingZeroBytes = BitOperations.LeadingZeroCount((uint)dl) / 8; + encoding[leadingZeroBytes] = (byte)(0x84 - leadingZeroBytes); + Write(encoding[leadingZeroBytes..]); +#else byte[] stack = new byte[5]; int pos = stack.Length; @@ -91,6 +104,7 @@ namespace Org.BouncyCastle.Asn1 stack[--pos] = (byte)(0x80 | count); Write(stack, pos, count + 1); +#endif } internal void WriteIdentifier(int tagClass, int tagNo) @@ -101,7 +115,11 @@ namespace Org.BouncyCastle.Asn1 return; } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + Span<byte> stack = stackalloc byte[6]; +#else byte[] stack = new byte[6]; +#endif int pos = stack.Length; stack[--pos] = (byte)(tagNo & 0x7F); @@ -113,7 +131,11 @@ namespace Org.BouncyCastle.Asn1 stack[--pos] = (byte)(tagClass | 0x1F); +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + Write(stack[pos..]); +#else Write(stack, pos, stack.Length - pos); +#endif } internal static IAsn1Encoding[] GetContentsEncodings(int encoding, Asn1Encodable[] elements) diff --git a/crypto/src/asn1/Asn1RelativeOid.cs b/crypto/src/asn1/Asn1RelativeOid.cs index d3c031913..a1997864d 100644 --- a/crypto/src/asn1/Asn1RelativeOid.cs +++ b/crypto/src/asn1/Asn1RelativeOid.cs @@ -196,7 +196,11 @@ namespace Org.BouncyCastle.Asn1 internal static void WriteField(Stream outputStream, long fieldValue) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + Span<byte> result = stackalloc byte[9]; +#else byte[] result = new byte[9]; +#endif int pos = 8; result[pos] = (byte)((int)fieldValue & 0x7F); while (fieldValue >= (1L << 7)) @@ -204,7 +208,11 @@ namespace Org.BouncyCastle.Asn1 fieldValue >>= 7; result[--pos] = (byte)((int)fieldValue | 0x80); } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + outputStream.Write(result[pos..]); +#else outputStream.Write(result, pos, 9 - pos); +#endif } internal static void WriteField(Stream outputStream, BigInteger fieldValue) @@ -217,14 +225,24 @@ namespace Org.BouncyCastle.Asn1 else { BigInteger tmpValue = fieldValue; +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + Span<byte> tmp = byteCount <= 16 + ? stackalloc byte[byteCount] + : new byte[byteCount]; +#else byte[] tmp = new byte[byteCount]; +#endif for (int i = byteCount - 1; i >= 0; i--) { tmp[i] = (byte)(tmpValue.IntValue | 0x80); tmpValue = tmpValue.ShiftRight(7); } tmp[byteCount - 1] &= 0x7F; +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + outputStream.Write(tmp); +#else outputStream.Write(tmp, 0, tmp.Length); +#endif } } diff --git a/crypto/src/asn1/Asn1Sequence.cs b/crypto/src/asn1/Asn1Sequence.cs index 3ceea4521..1a123e26d 100644 --- a/crypto/src/asn1/Asn1Sequence.cs +++ b/crypto/src/asn1/Asn1Sequence.cs @@ -195,6 +195,18 @@ namespace Org.BouncyCastle.Asn1 get { return elements.Length; } } + public virtual T[] MapElements<T>(Func<Asn1Encodable, T> func) + { + // NOTE: Call Count here to 'force' a LazyDerSequence + int count = Count; + T[] result = new T[count]; + for (int i = 0; i < count; ++i) + { + result[i] = func(elements[i]); + } + return result; + } + public virtual Asn1Encodable[] ToArray() { return Asn1EncodableVector.CloneElements(elements); @@ -246,26 +258,12 @@ namespace Org.BouncyCastle.Asn1 // TODO[asn1] Preferably return an Asn1BitString[] (doesn't exist yet) internal DerBitString[] GetConstructedBitStrings() { - // NOTE: Call Count here to 'force' a LazyDerSequence - int count = Count; - DerBitString[] bitStrings = new DerBitString[count]; - for (int i = 0; i < count; ++i) - { - bitStrings[i] = DerBitString.GetInstance(elements[i]); - } - return bitStrings; + return MapElements(DerBitString.GetInstance); } internal Asn1OctetString[] GetConstructedOctetStrings() { - // NOTE: Call Count here to 'force' a LazyDerSequence - int count = Count; - Asn1OctetString[] octetStrings = new Asn1OctetString[count]; - for (int i = 0; i < count; ++i) - { - octetStrings[i] = Asn1OctetString.GetInstance(elements[i]); - } - return octetStrings; + return MapElements(Asn1OctetString.GetInstance); } // TODO[asn1] Preferably return an Asn1BitString (doesn't exist yet) diff --git a/crypto/src/asn1/Asn1Set.cs b/crypto/src/asn1/Asn1Set.cs index 1045b7f74..faec50eb0 100644 --- a/crypto/src/asn1/Asn1Set.cs +++ b/crypto/src/asn1/Asn1Set.cs @@ -162,6 +162,18 @@ namespace Org.BouncyCastle.Asn1 get { return elements.Length; } } + public virtual T[] MapElements<T>(Func<Asn1Encodable, T> func) + { + // NOTE: Call Count here to 'force' a LazyDerSet + int count = Count; + T[] result = new T[count]; + for (int i = 0; i < count; ++i) + { + result[i] = func(elements[i]); + } + return result; + } + public virtual Asn1Encodable[] ToArray() { return Asn1EncodableVector.CloneElements(elements); @@ -294,6 +306,10 @@ namespace Org.BouncyCastle.Asn1 if (a0 != b0) return a0 < b0 ? -1 : 1; +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + int compareLength = System.Math.Min(a.Length, b.Length) - 1; + return a.AsSpan(1, compareLength).SequenceCompareTo(b.AsSpan(1, compareLength)); +#else int len = System.Math.Min(a.Length, b.Length); for (int i = 1; i < len; ++i) { @@ -303,6 +319,7 @@ namespace Org.BouncyCastle.Asn1 } Debug.Assert(a.Length == b.Length); return 0; +#endif } } } diff --git a/crypto/src/asn1/Asn1UniversalTypes.cs b/crypto/src/asn1/Asn1UniversalTypes.cs index 214918bcd..f5b5d0498 100644 --- a/crypto/src/asn1/Asn1UniversalTypes.cs +++ b/crypto/src/asn1/Asn1UniversalTypes.cs @@ -49,9 +49,9 @@ namespace Org.BouncyCastle.Asn1 case Asn1Tags.IA5String: // [UNIVERSAL 22] IMPLICIT OCTET STRING (encode as if) return DerIA5String.Meta.Instance; case Asn1Tags.UtcTime: // [UNIVERSAL 23] IMPLICIT VisibleString (restricted values) - return DerUtcTime.Meta.Instance; + return Asn1UtcTime.Meta.Instance; case Asn1Tags.GeneralizedTime: // [UNIVERSAL 24] IMPLICIT VisibleString (restricted values) - return DerGeneralizedTime.Meta.Instance; + return Asn1GeneralizedTime.Meta.Instance; case Asn1Tags.GraphicString: // [UNIVERSAL 25] IMPLICIT OCTET STRING (encode as if) return DerGraphicString.Meta.Instance; case Asn1Tags.VisibleString: // [UNIVERSAL 26] IMPLICIT OCTET STRING (encode as if) diff --git a/crypto/src/asn1/Asn1UtcTime.cs b/crypto/src/asn1/Asn1UtcTime.cs new file mode 100644 index 000000000..05de430c4 --- /dev/null +++ b/crypto/src/asn1/Asn1UtcTime.cs @@ -0,0 +1,264 @@ +using System; +using System.Globalization; +using System.IO; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1 +{ + /** + * UTC time object. + */ + public class Asn1UtcTime + : Asn1Object + { + internal class Meta : Asn1UniversalType + { + internal static readonly Asn1UniversalType Instance = new Meta(); + + private Meta() : base(typeof(Asn1UtcTime), Asn1Tags.UtcTime) {} + + internal override Asn1Object FromImplicitPrimitive(DerOctetString octetString) + { + return CreatePrimitive(octetString.GetOctets()); + } + } + + /** + * return a UTC Time from the passed in object. + * + * @exception ArgumentException if the object cannot be converted. + */ + public static Asn1UtcTime GetInstance(object obj) + { + if (obj == null) + return null; + + if (obj is Asn1UtcTime asn1UtcTime) + return asn1UtcTime; + + if (obj is IAsn1Convertible asn1Convertible) + { + Asn1Object asn1Object = asn1Convertible.ToAsn1Object(); + if (asn1Object is Asn1UtcTime converted) + return converted; + } + else if (obj is byte[] bytes) + { + try + { + return (Asn1UtcTime)Meta.Instance.FromByteArray(bytes); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct UTC time from byte[]: " + e.Message); + } + } + + throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); + } + + /** + * return a UTC Time from a tagged object. + * + * @param taggedObject the tagged object holding the object we want + * @param declaredExplicit true if the object is meant to be explicitly tagged false otherwise. + * @exception ArgumentException if the tagged object cannot be converted. + */ + public static Asn1UtcTime GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return (Asn1UtcTime)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit); + } + + private readonly string time; + + /** + * The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were + * never encoded. When you're creating one of these objects from scratch, that's + * what you want to use, otherwise we'll try to deal with whatever Gets read from + * the input stream... (this is why the input format is different from the GetTime() + * method output). + * <p> + * @param time the time string.</p> + */ + public Asn1UtcTime(string time) + { + if (time == null) + throw new ArgumentNullException("time"); + + this.time = time; + + try + { + ToDateTime(); + } + catch (FormatException e) + { + throw new ArgumentException("invalid date string: " + e.Message); + } + } + + /** + * base constructor from a DateTime object + */ + public Asn1UtcTime(DateTime time) + { + this.time = time.ToUniversalTime().ToString("yyMMddHHmmss", CultureInfo.InvariantCulture) + "Z"; + } + + internal Asn1UtcTime(byte[] contents) + { + // + // explicitly convert to characters + // + this.time = Strings.FromAsciiByteArray(contents); + } + + /** + * return the time as a date based on whatever a 2 digit year will return. For + * standardised processing use ToAdjustedDateTime(). + * + * @return the resulting date + * @exception ParseException if the date string cannot be parsed. + */ + public DateTime ToDateTime() + { + return ParseDateString(TimeString, @"yyMMddHHmmss'GMT'zzz"); + } + + /** + * return the time as an adjusted date + * in the range of 1950 - 2049. + * + * @return a date in the range of 1950 to 2049. + * @exception ParseException if the date string cannot be parsed. + */ + public DateTime ToAdjustedDateTime() + { + return ParseDateString(AdjustedTimeString, @"yyyyMMddHHmmss'GMT'zzz"); + } + + private DateTime ParseDateString(string dateStr, string formatStr) + { + DateTime dt = DateTime.ParseExact( + dateStr, + formatStr, + DateTimeFormatInfo.InvariantInfo); + + return dt.ToUniversalTime(); + } + + /** + * return the time - always in the form of + * YYMMDDhhmmssGMT(+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("yyMMddHHmmssz"); + * </pre> + * To read in the time and Get a date which is compatible with our local + * time zone.</p> + * <p> + * <b>Note:</b> In some cases, due to the local date processing, this + * may lead to unexpected results. If you want to stick the normal + * convention of 1950 to 2049 use the GetAdjustedTime() method.</p> + */ + public string TimeString + { + get + { + // + // standardise the format. + // + if (time.IndexOf('-') < 0 && time.IndexOf('+') < 0) + { + if (time.Length == 11) + { + return time.Substring(0, 10) + "00GMT+00:00"; + } + else + { + return time.Substring(0, 12) + "GMT+00:00"; + } + } + else + { + int index = time.IndexOf('-'); + if (index < 0) + { + index = time.IndexOf('+'); + } + string d = time; + + if (index == time.Length - 3) + { + d += "00"; + } + + if (index == 10) + { + return d.Substring(0, 10) + "00GMT" + d.Substring(10, 3) + ":" + d.Substring(13, 2); + } + else + { + return d.Substring(0, 12) + "GMT" + d.Substring(12, 3) + ":" + d.Substring(15, 2); + } + } + } + } + + /// <summary> + /// Return a time string as an adjusted date with a 4 digit year. + /// This goes in the range of 1950 - 2049. + /// </summary> + public string AdjustedTimeString + { + get + { + string d = TimeString; + string c = d[0] < '5' ? "20" : "19"; + + return c + d; + } + } + + internal byte[] GetOctets() + { + return Strings.ToAsciiByteArray(time); + } + + internal override IAsn1Encoding GetEncoding(int encoding) + { + return new PrimitiveEncoding(Asn1Tags.Universal, Asn1Tags.UtcTime, GetOctets()); + } + + internal override IAsn1Encoding GetEncodingImplicit(int encoding, int tagClass, int tagNo) + { + return new PrimitiveEncoding(tagClass, tagNo, GetOctets()); + } + + protected override bool Asn1Equals(Asn1Object asn1Object) + { + if (!(asn1Object is Asn1UtcTime that)) + return false; + + return this.time == that.time; + } + + protected override int Asn1GetHashCode() + { + return time.GetHashCode(); + } + + public override string ToString() + { + return time; + } + + internal static Asn1UtcTime CreatePrimitive(byte[] contents) + { + return new Asn1UtcTime(contents); + } + } +} diff --git a/crypto/src/asn1/BEROctetStringGenerator.cs b/crypto/src/asn1/BEROctetStringGenerator.cs index 7893139d6..b07576e7d 100644 --- a/crypto/src/asn1/BEROctetStringGenerator.cs +++ b/crypto/src/asn1/BEROctetStringGenerator.cs @@ -64,6 +64,9 @@ namespace Org.BouncyCastle.Asn1 { Streams.ValidateBufferArguments(buffer, offset, count); +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + Write(buffer.AsSpan(offset, count)); +#else int bufLen = _buf.Length; int available = bufLen - _off; if (count < available) @@ -77,8 +80,9 @@ namespace Org.BouncyCastle.Asn1 if (_off > 0) { Array.Copy(buffer, offset, _buf, _off, available); - pos += available; + pos = available; DerOctetString.Encode(_derOut, _buf, 0, bufLen); + //_off = 0; } int remaining; @@ -90,9 +94,40 @@ namespace Org.BouncyCastle.Asn1 Array.Copy(buffer, offset + pos, _buf, 0, remaining); this._off = remaining; +#endif + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override void Write(ReadOnlySpan<byte> buffer) + { + int bufLen = _buf.Length; + int available = bufLen - _off; + if (buffer.Length < available) + { + buffer.CopyTo(_buf.AsSpan(_off)); + _off += buffer.Length; + return; + } + + if (_off > 0) + { + DerOctetString.Encode(_derOut, _buf.AsSpan(0, _off), buffer[..available]); + buffer = buffer[available..]; + //_off = 0; + } + + while (buffer.Length >= bufLen) + { + DerOctetString.Encode(_derOut, buffer[..bufLen]); + buffer = buffer[bufLen..]; + } + + buffer.CopyTo(_buf.AsSpan()); + _off = buffer.Length; } +#endif - public override void WriteByte(byte value) + public override void WriteByte(byte value) { _buf[_off++] = value; @@ -103,33 +138,20 @@ namespace Org.BouncyCastle.Asn1 } } -#if PORTABLE protected override void Dispose(bool disposing) { if (disposing) { - ImplClose(); - } - base.Dispose(disposing); - } -#else - public override void Close() - { - ImplClose(); - base.Close(); - } -#endif - - private void ImplClose() - { - if (_off != 0) - { - DerOctetString.Encode(_derOut, _buf, 0, _off); - } + if (_off != 0) + { + DerOctetString.Encode(_derOut, _buf, 0, _off); + } - _derOut.FlushInternal(); + _derOut.FlushInternal(); - _gen.WriteBerEnd(); + _gen.WriteBerEnd(); + } + base.Dispose(disposing); } } } diff --git a/crypto/src/asn1/ConstructedBitStream.cs b/crypto/src/asn1/ConstructedBitStream.cs index 49f54fc1b..f089dac75 100644 --- a/crypto/src/asn1/ConstructedBitStream.cs +++ b/crypto/src/asn1/ConstructedBitStream.cs @@ -33,6 +33,9 @@ namespace Org.BouncyCastle.Asn1 { Streams.ValidateBufferArguments(buffer, offset, count); +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return Read(buffer.AsSpan(offset, count)); +#else if (count < 1) return 0; @@ -75,8 +78,57 @@ namespace Org.BouncyCastle.Asn1 m_currentStream = m_currentParser.GetBitStream(); } } +#endif } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override int Read(Span<byte> buffer) + { + if (buffer.IsEmpty) + return 0; + + if (m_currentStream == null) + { + if (!m_first) + return 0; + + m_currentParser = GetNextParser(); + if (m_currentParser == null) + return 0; + + m_first = false; + m_currentStream = m_currentParser.GetBitStream(); + } + + int totalRead = 0; + + for (;;) + { + int numRead = m_currentStream.Read(buffer[totalRead..]); + + if (numRead > 0) + { + totalRead += numRead; + + if (totalRead == buffer.Length) + return totalRead; + } + else + { + m_padBits = m_currentParser.PadBits; + m_currentParser = GetNextParser(); + if (m_currentParser == null) + { + m_currentStream = null; + return totalRead; + } + + m_currentStream = m_currentParser.GetBitStream(); + } + } + } +#endif + public override int ReadByte() { if (m_currentStream == null) diff --git a/crypto/src/asn1/ConstructedOctetStream.cs b/crypto/src/asn1/ConstructedOctetStream.cs index 12aa14e74..d005f9fe7 100644 --- a/crypto/src/asn1/ConstructedOctetStream.cs +++ b/crypto/src/asn1/ConstructedOctetStream.cs @@ -1,3 +1,4 @@ +using System; using System.IO; using Org.BouncyCastle.Utilities; @@ -22,6 +23,9 @@ namespace Org.BouncyCastle.Asn1 { Streams.ValidateBufferArguments(buffer, offset, count); +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + return Read(buffer.AsSpan(offset, count)); +#else if (count < 1) return 0; @@ -63,8 +67,56 @@ namespace Org.BouncyCastle.Asn1 m_currentStream = next.GetOctetStream(); } } +#endif } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override int Read(Span<byte> buffer) + { + if (buffer.IsEmpty) + return 0; + + if (m_currentStream == null) + { + if (!m_first) + return 0; + + Asn1OctetStringParser next = GetNextParser(); + if (next == null) + return 0; + + m_first = false; + m_currentStream = next.GetOctetStream(); + } + + int totalRead = 0; + + for (;;) + { + int numRead = m_currentStream.Read(buffer[totalRead..]); + + if (numRead > 0) + { + totalRead += numRead; + + if (totalRead == buffer.Length) + return totalRead; + } + else + { + Asn1OctetStringParser next = GetNextParser(); + if (next == null) + { + m_currentStream = null; + return totalRead; + } + + m_currentStream = next.GetOctetStream(); + } + } + } +#endif + public override int ReadByte() { if (m_currentStream == null) diff --git a/crypto/src/asn1/DefiniteLengthInputStream.cs b/crypto/src/asn1/DefiniteLengthInputStream.cs index ed5bd2446..89f0d5a62 100644 --- a/crypto/src/asn1/DefiniteLengthInputStream.cs +++ b/crypto/src/asn1/DefiniteLengthInputStream.cs @@ -79,6 +79,27 @@ namespace Org.BouncyCastle.Asn1 return numRead; } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override int Read(Span<byte> buffer) + { + if (_remaining == 0) + return 0; + + int toRead = System.Math.Min(buffer.Length, _remaining); + int numRead = _in.Read(buffer[..toRead]); + + if (numRead < 1) + throw new EndOfStreamException("DEF length " + _originalLength + " object truncated by " + _remaining); + + if ((_remaining -= numRead) == 0) + { + SetParentEofDetect(); + } + + return numRead; + } +#endif + internal void ReadAllIntoByteArray(byte[] buf) { if (_remaining != buf.Length) diff --git a/crypto/src/asn1/DerGeneralizedTime.cs b/crypto/src/asn1/DerGeneralizedTime.cs index 16774cb02..0386ecb02 100644 --- a/crypto/src/asn1/DerGeneralizedTime.cs +++ b/crypto/src/asn1/DerGeneralizedTime.cs @@ -1,326 +1,33 @@ using System; -using System.Globalization; -using System.IO; -using System.Text; - -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1 { - /** - * Generalized time object. - */ public class DerGeneralizedTime - : Asn1Object + : Asn1GeneralizedTime { - internal class Meta : Asn1UniversalType - { - internal static readonly Asn1UniversalType Instance = new Meta(); - - private Meta() : base(typeof(DerGeneralizedTime), Asn1Tags.GeneralizedTime) {} - - internal override Asn1Object FromImplicitPrimitive(DerOctetString octetString) - { - return CreatePrimitive(octetString.GetOctets()); - } - } - - /** - * 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; - } - else if (obj is IAsn1Convertible) - { - Asn1Object asn1Object = ((IAsn1Convertible)obj).ToAsn1Object(); - if (asn1Object is DerGeneralizedTime) - return (DerGeneralizedTime)asn1Object; - } - else if (obj is byte[]) - { - try - { - return (DerGeneralizedTime)Meta.Instance.FromByteArray((byte[])obj); - } - catch (IOException e) - { - throw new ArgumentException("failed to construct generalized time from byte[]: " + e.Message); - } - } - - throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); - } - - /** - * return a generalized Time object from a tagged object. - * - * @param taggedObject the tagged object holding the object we want - * @param declaredExplicit 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 taggedObject, bool declaredExplicit) - { - return (DerGeneralizedTime)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit); - } - - private readonly string time; - - /** - * 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) + public DerGeneralizedTime(byte[] time) + : base(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) + : base(time) { - this.time = time.ToUniversalTime().ToString(@"yyyyMMddHHmmss\Z"); - } - - 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(); - - TimeSpan offset = TimeZoneInfo.Local.GetUtcOffset(time); - if (offset.CompareTo(TimeSpan.Zero) < 0) - { - sign = '-'; - offset = offset.Duration(); - } - int hours = offset.Hours; - int minutes = offset.Minutes; - - 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 (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 = 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) + public DerGeneralizedTime(string time) + : base(time) { - /* - * NOTE: DateTime.Kind and DateTimeStyles.AssumeUniversal not available in .NET 1.1 - */ - DateTimeStyles style = DateTimeStyles.None; - if (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 IAsn1Encoding GetEncoding(int encoding) { - return new PrimitiveEncoding(Asn1Tags.Universal, Asn1Tags.GeneralizedTime, GetOctets()); + return new PrimitiveEncoding(Asn1Tags.Universal, Asn1Tags.GeneralizedTime, GetDerTime()); } internal override IAsn1Encoding GetEncodingImplicit(int encoding, int tagClass, int tagNo) { - return new PrimitiveEncoding(tagClass, tagNo, GetOctets()); - } - - protected override bool Asn1Equals(Asn1Object asn1Object) - { - DerGeneralizedTime that = asn1Object as DerGeneralizedTime; - return null != that - && this.time.Equals(that.time); - } - - protected override int Asn1GetHashCode() - { - return time.GetHashCode(); - } - - internal static DerGeneralizedTime CreatePrimitive(byte[] contents) - { - return new DerGeneralizedTime(contents); + return new PrimitiveEncoding(tagClass, tagNo, GetDerTime()); } } } diff --git a/crypto/src/asn1/DerOctetString.cs b/crypto/src/asn1/DerOctetString.cs index d9913f065..ea13765ec 100644 --- a/crypto/src/asn1/DerOctetString.cs +++ b/crypto/src/asn1/DerOctetString.cs @@ -37,5 +37,22 @@ namespace Org.BouncyCastle.Asn1 asn1Out.WriteDL(len); asn1Out.Write(buf, off, len); } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + internal static void Encode(Asn1OutputStream asn1Out, ReadOnlySpan<byte> buf) + { + asn1Out.WriteIdentifier(Asn1Tags.Universal, Asn1Tags.OctetString); + asn1Out.WriteDL(buf.Length); + asn1Out.Write(buf); + } + + internal static void Encode(Asn1OutputStream asn1Out, ReadOnlySpan<byte> buf1, ReadOnlySpan<byte> buf2) + { + asn1Out.WriteIdentifier(Asn1Tags.Universal, Asn1Tags.OctetString); + asn1Out.WriteDL(buf1.Length + buf2.Length); + asn1Out.Write(buf1); + asn1Out.Write(buf2); + } +#endif } } diff --git a/crypto/src/asn1/DerUTCTime.cs b/crypto/src/asn1/DerUTCTime.cs index 7f7756d49..089285367 100644 --- a/crypto/src/asn1/DerUTCTime.cs +++ b/crypto/src/asn1/DerUTCTime.cs @@ -1,274 +1,25 @@ using System; -using System.Globalization; -using System.IO; - -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1 { - /** - * UTC time object. - */ public class DerUtcTime - : Asn1Object + : Asn1UtcTime { - internal class Meta : Asn1UniversalType - { - internal static readonly Asn1UniversalType Instance = new Meta(); - - private Meta() : base(typeof(DerUtcTime), Asn1Tags.UtcTime) {} - - internal override Asn1Object FromImplicitPrimitive(DerOctetString octetString) - { - return CreatePrimitive(octetString.GetOctets()); - } - } - - /** - * return a UTC Time from the passed in object. - * - * @exception ArgumentException if the object cannot be converted. - */ - public static DerUtcTime GetInstance(object obj) - { - if (obj == null || obj is DerUtcTime) - { - return (DerUtcTime)obj; - } - else if (obj is IAsn1Convertible) - { - Asn1Object asn1Object = ((IAsn1Convertible)obj).ToAsn1Object(); - if (asn1Object is DerUtcTime) - return (DerUtcTime)asn1Object; - } - else if (obj is byte[]) - { - try - { - return (DerUtcTime)Meta.Instance.FromByteArray((byte[])obj); - } - catch (IOException e) - { - throw new ArgumentException("failed to construct UTC time from byte[]: " + e.Message); - } - } - - throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); - } - - /** - * return a UTC Time from a tagged object. - * - * @param taggedObject the tagged object holding the object we want - * @param declaredExplicit true if the object is meant to be explicitly tagged false otherwise. - * @exception ArgumentException if the tagged object cannot be converted. - */ - public static DerUtcTime GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) - { - return (DerUtcTime)Meta.Instance.GetContextInstance(taggedObject, declaredExplicit); - } - - private readonly string time; - - /** - * The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were - * never encoded. When you're creating one of these objects from scratch, that's - * what you want to use, otherwise we'll try to deal with whatever Gets read from - * the input stream... (this is why the input format is different from the GetTime() - * method output). - * <p> - * @param time the time string.</p> - */ public DerUtcTime(string time) + : base(time) { - if (time == null) - throw new ArgumentNullException("time"); - - this.time = time; - - try - { - ToDateTime(); - } - catch (FormatException e) - { - throw new ArgumentException("invalid date string: " + e.Message); - } } - /** - * base constructor from a DateTime object - */ public DerUtcTime(DateTime time) + : base(time) { - this.time = time.ToUniversalTime().ToString("yyMMddHHmmss", CultureInfo.InvariantCulture) + "Z"; } internal DerUtcTime(byte[] contents) + : base(contents) { - // - // explicitly convert to characters - // - this.time = Strings.FromAsciiByteArray(contents); - } - -// public DateTime ToDateTime() -// { -// string tm = this.AdjustedTimeString; -// -// return new DateTime( -// Int16.Parse(tm.Substring(0, 4)), -// Int16.Parse(tm.Substring(4, 2)), -// Int16.Parse(tm.Substring(6, 2)), -// Int16.Parse(tm.Substring(8, 2)), -// Int16.Parse(tm.Substring(10, 2)), -// Int16.Parse(tm.Substring(12, 2))); -// } - - /** - * return the time as a date based on whatever a 2 digit year will return. For - * standardised processing use ToAdjustedDateTime(). - * - * @return the resulting date - * @exception ParseException if the date string cannot be parsed. - */ - public DateTime ToDateTime() - { - return ParseDateString(TimeString, @"yyMMddHHmmss'GMT'zzz"); - } - - /** - * return the time as an adjusted date - * in the range of 1950 - 2049. - * - * @return a date in the range of 1950 to 2049. - * @exception ParseException if the date string cannot be parsed. - */ - public DateTime ToAdjustedDateTime() - { - return ParseDateString(AdjustedTimeString, @"yyyyMMddHHmmss'GMT'zzz"); - } - - private DateTime ParseDateString(string dateStr, string formatStr) - { - DateTime dt = DateTime.ParseExact( - dateStr, - formatStr, - DateTimeFormatInfo.InvariantInfo); - - return dt.ToUniversalTime(); - } - - /** - * return the time - always in the form of - * YYMMDDhhmmssGMT(+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("yyMMddHHmmssz"); - * </pre> - * To read in the time and Get a date which is compatible with our local - * time zone.</p> - * <p> - * <b>Note:</b> In some cases, due to the local date processing, this - * may lead to unexpected results. If you want to stick the normal - * convention of 1950 to 2049 use the GetAdjustedTime() method.</p> - */ - public string TimeString - { - get - { - // - // standardise the format. - // - if (time.IndexOf('-') < 0 && time.IndexOf('+') < 0) - { - if (time.Length == 11) - { - return time.Substring(0, 10) + "00GMT+00:00"; - } - else - { - return time.Substring(0, 12) + "GMT+00:00"; - } - } - else - { - int index = time.IndexOf('-'); - if (index < 0) - { - index = time.IndexOf('+'); - } - string d = time; - - if (index == time.Length - 3) - { - d += "00"; - } - - if (index == 10) - { - return d.Substring(0, 10) + "00GMT" + d.Substring(10, 3) + ":" + d.Substring(13, 2); - } - else - { - return d.Substring(0, 12) + "GMT" + d.Substring(12, 3) + ":" + d.Substring(15, 2); - } - } - } - } - - /// <summary> - /// Return a time string as an adjusted date with a 4 digit year. - /// This goes in the range of 1950 - 2049. - /// </summary> - public string AdjustedTimeString - { - get - { - string d = TimeString; - string c = d[0] < '5' ? "20" : "19"; - - return c + d; - } - } - - private byte[] GetOctets() - { - return Strings.ToAsciiByteArray(time); - } - - internal override IAsn1Encoding GetEncoding(int encoding) - { - return new PrimitiveEncoding(Asn1Tags.Universal, Asn1Tags.UtcTime, GetOctets()); - } - - internal override IAsn1Encoding GetEncodingImplicit(int encoding, int tagClass, int tagNo) - { - return new PrimitiveEncoding(tagClass, tagNo, GetOctets()); - } - - protected override bool Asn1Equals(Asn1Object asn1Object) - { - DerUtcTime that = asn1Object as DerUtcTime; - return null != that - && this.time.Equals(that.time); } - protected override int Asn1GetHashCode() - { - return time.GetHashCode(); - } - - public override string ToString() - { - return time; - } - - internal static DerUtcTime CreatePrimitive(byte[] contents) - { - return new DerUtcTime(contents); - } + // TODO: create proper DER encoding. } } diff --git a/crypto/src/asn1/IndefiniteLengthInputStream.cs b/crypto/src/asn1/IndefiniteLengthInputStream.cs index 1c8bd9a15..e192e9e8b 100644 --- a/crypto/src/asn1/IndefiniteLengthInputStream.cs +++ b/crypto/src/asn1/IndefiniteLengthInputStream.cs @@ -57,7 +57,28 @@ namespace Org.BouncyCastle.Asn1 return numRead + 1; } - public override int ReadByte() +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override int Read(Span<byte> buffer) + { + // Only use this optimisation if we aren't checking for 00 + if (_eofOn00 || buffer.Length <= 1) + return base.Read(buffer); + + if (_lookAhead < 0) + return 0; + + int numRead = _in.Read(buffer[1..]); + if (numRead <= 0) + throw new EndOfStreamException(); + + buffer[0] = (byte)_lookAhead; + _lookAhead = RequireByte(); + + return numRead + 1; + } +#endif + + public override int ReadByte() { if (_eofOn00 && _lookAhead <= 0) { diff --git a/crypto/src/asn1/bc/BCObjectIdentifiers.cs b/crypto/src/asn1/bc/BCObjectIdentifiers.cs index a649e0c73..d526980e5 100644 --- a/crypto/src/asn1/bc/BCObjectIdentifiers.cs +++ b/crypto/src/asn1/bc/BCObjectIdentifiers.cs @@ -116,6 +116,27 @@ namespace Org.BouncyCastle.Asn1.BC public static readonly DerObjectIdentifier picnicl1full = picnic.Branch("10"); public static readonly DerObjectIdentifier picnicl3full = picnic.Branch("11"); public static readonly DerObjectIdentifier picnicl5full = picnic.Branch("12"); + + /* + * Falcon + */ + public static readonly DerObjectIdentifier falcon = bc_sig.Branch("7"); + + public static readonly DerObjectIdentifier falcon_512 = new DerObjectIdentifier("1.3.9999.3.1"); // falcon.branch("1"); + public static readonly DerObjectIdentifier falcon_1024 = new DerObjectIdentifier("1.3.9999.3.4"); // falcon.branch("2"); + + /* + * Dilithium + */ + public static readonly DerObjectIdentifier dilithium = bc_sig.Branch("8"); + + // OpenSSL OIDs + public static readonly DerObjectIdentifier dilithium2 = new DerObjectIdentifier("1.3.6.1.4.1.2.267.7.4.4"); // dilithium.branch("1"); + public static readonly DerObjectIdentifier dilithium3 = new DerObjectIdentifier("1.3.6.1.4.1.2.267.7.6.5"); // dilithium.branch("2"); + public static readonly DerObjectIdentifier dilithium5 = new DerObjectIdentifier("1.3.6.1.4.1.2.267.7.8.7"); // dilithium.branch("3"); + public static readonly DerObjectIdentifier dilithium2_aes = new DerObjectIdentifier("1.3.6.1.4.1.2.267.11.4.4"); // dilithium.branch("4"); + public static readonly DerObjectIdentifier dilithium3_aes = new DerObjectIdentifier("1.3.6.1.4.1.2.267.11.6.5"); // dilithium.branch("5"); + public static readonly DerObjectIdentifier dilithium5_aes = new DerObjectIdentifier("1.3.6.1.4.1.2.267.11.8.7"); // dilithium.branch("6"); /** @@ -171,7 +192,16 @@ namespace Org.BouncyCastle.Asn1.BC public static readonly DerObjectIdentifier lightsaberkem256r3 = pqc_kem_saber.Branch("7"); public static readonly DerObjectIdentifier saberkem256r3 = pqc_kem_saber.Branch("8"); public static readonly DerObjectIdentifier firesaberkem256r3 = pqc_kem_saber.Branch("9"); - + public static readonly DerObjectIdentifier ulightsaberkemr3 = pqc_kem_saber.Branch("10"); + public static readonly DerObjectIdentifier usaberkemr3 = pqc_kem_saber.Branch("11"); + public static readonly DerObjectIdentifier ufiresaberkemr3 = pqc_kem_saber.Branch("12"); + public static readonly DerObjectIdentifier lightsaberkem90sr3 = pqc_kem_saber.Branch("13"); + public static readonly DerObjectIdentifier saberkem90sr3 = pqc_kem_saber.Branch("14"); + public static readonly DerObjectIdentifier firesaberkem90sr3 = pqc_kem_saber.Branch("15"); + public static readonly DerObjectIdentifier ulightsaberkem90sr3 = pqc_kem_saber.Branch("16"); + public static readonly DerObjectIdentifier usaberkem90sr3 = pqc_kem_saber.Branch("17"); + public static readonly DerObjectIdentifier ufiresaberkem90sr3 = pqc_kem_saber.Branch("18"); + /** * SIKE */ @@ -184,5 +214,35 @@ namespace Org.BouncyCastle.Asn1.BC public static readonly DerObjectIdentifier sikep503_compressed = pqc_kem_sike.Branch("6"); public static readonly DerObjectIdentifier sikep610_compressed = pqc_kem_sike.Branch("7"); public static readonly DerObjectIdentifier sikep751_compressed = pqc_kem_sike.Branch("8"); - } + + /** + * Kyber + */ + public static readonly DerObjectIdentifier pqc_kem_kyber = bc_kem.Branch("6"); + + public static readonly DerObjectIdentifier kyber512 = new DerObjectIdentifier("1.3.6.1.4.1.2.267.8.2.2"); // pqc_kem_kyber.Branch("1"); + public static readonly DerObjectIdentifier kyber768 = new DerObjectIdentifier("1.3.6.1.4.1.2.267.8.3.3"); // pqc_kem_kyber.Branch("2"); + public static readonly DerObjectIdentifier kyber1024 = new DerObjectIdentifier("1.3.6.1.4.1.2.267.8.4.4"); // pqc_kem_kyber.Branch("3"); + public static readonly DerObjectIdentifier kyber512_aes = new DerObjectIdentifier("1.3.6.1.4.1.2.267.10.2.2"); // pqc_kem_kyber.Branch("4"); + public static readonly DerObjectIdentifier kyber768_aes = new DerObjectIdentifier("1.3.6.1.4.1.2.267.10.3.3"); // pqc_kem_kyber.Branch("5"); + public static readonly DerObjectIdentifier kyber1024_aes = new DerObjectIdentifier("1.3.6.1.4.1.2.267.10.4.4"); // pqc_kem_kyber.Branch("6"); + + /** + * BIKE + */ + public static readonly DerObjectIdentifier pqc_kem_bike = bc_kem.Branch("8"); + + public static readonly DerObjectIdentifier bike128 = pqc_kem_bike.Branch("1"); + public static readonly DerObjectIdentifier bike192 = pqc_kem_bike.Branch("2"); + public static readonly DerObjectIdentifier bike256 = pqc_kem_bike.Branch("3"); + + /** + * HQC + */ + public static readonly DerObjectIdentifier pqc_kem_hqc = bc_kem.Branch("9"); + + public static readonly DerObjectIdentifier hqc128 = pqc_kem_hqc.Branch("1"); + public static readonly DerObjectIdentifier hqc192 = pqc_kem_hqc.Branch("2"); + public static readonly DerObjectIdentifier hqc256 = pqc_kem_hqc.Branch("3"); + } } diff --git a/crypto/src/asn1/cmp/CAKeyUpdAnnContent.cs b/crypto/src/asn1/cmp/CAKeyUpdAnnContent.cs index b74bac87a..a3ec5e4df 100644 --- a/crypto/src/asn1/cmp/CAKeyUpdAnnContent.cs +++ b/crypto/src/asn1/cmp/CAKeyUpdAnnContent.cs @@ -7,42 +7,33 @@ namespace Org.BouncyCastle.Asn1.Cmp public class CAKeyUpdAnnContent : Asn1Encodable { - private readonly CmpCertificate oldWithNew; - private readonly CmpCertificate newWithOld; - private readonly CmpCertificate newWithNew; + public static CAKeyUpdAnnContent GetInstance(object obj) + { + if (obj is CAKeyUpdAnnContent content) + return content; - private CAKeyUpdAnnContent(Asn1Sequence seq) - { - oldWithNew = CmpCertificate.GetInstance(seq[0]); - newWithOld = CmpCertificate.GetInstance(seq[1]); - newWithNew = CmpCertificate.GetInstance(seq[2]); - } + if (obj is Asn1Sequence seq) + return new CAKeyUpdAnnContent(seq); - public static CAKeyUpdAnnContent GetInstance(object obj) - { - if (obj is CAKeyUpdAnnContent) - return (CAKeyUpdAnnContent)obj; + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), nameof(obj)); + } - if (obj is Asn1Sequence) - return new CAKeyUpdAnnContent((Asn1Sequence)obj); + private readonly CmpCertificate m_oldWithNew; + private readonly CmpCertificate m_newWithOld; + private readonly CmpCertificate m_newWithNew; - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); - } - - public virtual CmpCertificate OldWithNew - { - get { return oldWithNew; } - } - - public virtual CmpCertificate NewWithOld + private CAKeyUpdAnnContent(Asn1Sequence seq) { - get { return newWithOld; } + m_oldWithNew = CmpCertificate.GetInstance(seq[0]); + m_newWithOld = CmpCertificate.GetInstance(seq[1]); + m_newWithNew = CmpCertificate.GetInstance(seq[2]); } - public virtual CmpCertificate NewWithNew - { - get { return newWithNew; } - } + public virtual CmpCertificate OldWithNew => m_oldWithNew; + + public virtual CmpCertificate NewWithOld => m_newWithOld; + + public virtual CmpCertificate NewWithNew => m_newWithNew; /** * <pre> @@ -56,7 +47,7 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - return new DerSequence(oldWithNew, newWithOld, newWithNew); + return new DerSequence(m_oldWithNew, m_newWithOld, m_newWithNew); } } } diff --git a/crypto/src/asn1/cmp/CertAnnContent.cs b/crypto/src/asn1/cmp/CertAnnContent.cs new file mode 100644 index 000000000..30b1fad2f --- /dev/null +++ b/crypto/src/asn1/cmp/CertAnnContent.cs @@ -0,0 +1,72 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + /** + * CertAnnContent ::= CMPCertificate + */ + public class CertAnnContent + : CmpCertificate + { + public static new CertAnnContent GetInstance(object obj) + { + // TODO[cmp] + if (obj == null) + return null; + + if (obj is CertAnnContent content) + return content; + + if (obj is CmpCertificate cmpCertificate) + return GetInstance(cmpCertificate.GetEncoded()); + + if (obj is byte[] bs) + { + try + { + obj = Asn1Object.FromByteArray(bs); + } + catch (IOException) + { + throw new ArgumentException("Invalid encoding in CertAnnContent"); + } + } + + if (obj is Asn1Sequence) + return new CertAnnContent(X509CertificateStructure.GetInstance(obj)); + + // TODO[cmp] + if (obj is Asn1TaggedObject taggedObject) + return new CertAnnContent(taggedObject.TagNo, taggedObject.GetObject()); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), nameof(obj)); + } + + public static new CertAnnContent GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + // TODO[cmp] + if (taggedObject == null) + return null; + + if (!declaredExplicit) + throw new ArgumentException("tag must be explicit"); + + // TODO[cmp] + return GetInstance(taggedObject.GetObject()); + } + + public CertAnnContent(int type, Asn1Object otherCert) + : base(type, otherCert) + { + } + + public CertAnnContent(X509CertificateStructure x509v3PKCert) + : base(x509v3PKCert) + { + } + } +} diff --git a/crypto/src/asn1/cmp/CertConfirmContent.cs b/crypto/src/asn1/cmp/CertConfirmContent.cs index 370a9e7d6..8e75dfbd0 100644 --- a/crypto/src/asn1/cmp/CertConfirmContent.cs +++ b/crypto/src/asn1/cmp/CertConfirmContent.cs @@ -7,32 +7,27 @@ namespace Org.BouncyCastle.Asn1.Cmp public class CertConfirmContent : Asn1Encodable { - private readonly Asn1Sequence content; - - private CertConfirmContent(Asn1Sequence seq) - { - content = seq; - } - public static CertConfirmContent GetInstance(object obj) { - if (obj is CertConfirmContent) - return (CertConfirmContent)obj; + if (obj is CertConfirmContent content) + return content; - if (obj is Asn1Sequence) - return new CertConfirmContent((Asn1Sequence)obj); + if (obj is Asn1Sequence seq) + return new CertConfirmContent(seq); - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), nameof(obj)); } - public virtual CertStatus[] ToCertStatusArray() + private readonly Asn1Sequence m_content; + + private CertConfirmContent(Asn1Sequence seq) + { + m_content = seq; + } + + public virtual CertStatus[] ToCertStatusArray() { - CertStatus[] result = new CertStatus[content.Count]; - for (int i = 0; i != result.Length; i++) - { - result[i] = CertStatus.GetInstance(content[i]); - } - return result; + return m_content.MapElements(CertStatus.GetInstance); } /** @@ -43,7 +38,7 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - return content; + return m_content; } } } diff --git a/crypto/src/asn1/cmp/CertOrEncCert.cs b/crypto/src/asn1/cmp/CertOrEncCert.cs index eb200e1e8..e517b66ce 100644 --- a/crypto/src/asn1/cmp/CertOrEncCert.cs +++ b/crypto/src/asn1/cmp/CertOrEncCert.cs @@ -8,79 +8,79 @@ namespace Org.BouncyCastle.Asn1.Cmp public class CertOrEncCert : Asn1Encodable, IAsn1Choice { - private readonly CmpCertificate certificate; - private readonly EncryptedValue encryptedCert; + public static CertOrEncCert GetInstance(object obj) + { + if (obj is CertOrEncCert certOrEncCert) + return certOrEncCert; - private CertOrEncCert(Asn1TaggedObject tagged) + if (obj is Asn1TaggedObject taggedObject) + return new CertOrEncCert(taggedObject); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), nameof(obj)); + } + + private readonly CmpCertificate m_certificate; + private readonly EncryptedKey m_encryptedCert; + + private CertOrEncCert(Asn1TaggedObject taggedObject) { - if (tagged.TagNo == 0) + if (taggedObject.TagNo == 0) { - certificate = CmpCertificate.GetInstance(tagged.GetObject()); + m_certificate = CmpCertificate.GetInstance(taggedObject.GetObject()); } - else if (tagged.TagNo == 1) + else if (taggedObject.TagNo == 1) { - encryptedCert = EncryptedValue.GetInstance(tagged.GetObject()); + m_encryptedCert = EncryptedKey.GetInstance(taggedObject.GetObject()); } else { - throw new ArgumentException("unknown tag: " + tagged.TagNo, "tagged"); - } - } - - public static CertOrEncCert GetInstance(object obj) - { - if (obj is CertOrEncCert) - return (CertOrEncCert)obj; - - if (obj is Asn1TaggedObject) - return new CertOrEncCert((Asn1TaggedObject)obj); - - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); - } + throw new ArgumentException("unknown tag: " + taggedObject.TagNo, nameof(taggedObject)); + } + } public CertOrEncCert(CmpCertificate certificate) { if (certificate == null) - throw new ArgumentNullException("certificate"); + throw new ArgumentNullException(nameof(certificate)); - this.certificate = certificate; + m_certificate = certificate; } - public CertOrEncCert(EncryptedValue encryptedCert) + public CertOrEncCert(EncryptedValue encryptedValue) { - if (encryptedCert == null) - throw new ArgumentNullException("encryptedCert"); + if (encryptedValue == null) + throw new ArgumentNullException(nameof(encryptedValue)); - this.encryptedCert = encryptedCert; + m_encryptedCert = new EncryptedKey(encryptedValue); } - public virtual CmpCertificate Certificate - { - get { return certificate; } - } + public CertOrEncCert(EncryptedKey encryptedKey) + { + if (encryptedKey == null) + throw new ArgumentNullException(nameof(encryptedKey)); - public virtual EncryptedValue EncryptedCert - { - get { return encryptedCert; } - } + m_encryptedCert = encryptedKey; + } - /** + public virtual CmpCertificate Certificate => m_certificate; + + public virtual EncryptedKey EncryptedCert => m_encryptedCert; + + /** * <pre> * CertOrEncCert ::= CHOICE { * certificate [0] CMPCertificate, - * encryptedCert [1] EncryptedValue + * encryptedCert [1] EncryptedKey * } * </pre> * @return a basic ASN.1 object representation. */ - public override Asn1Object ToAsn1Object() + public override Asn1Object ToAsn1Object() { - if (certificate != null) - { - return new DerTaggedObject(true, 0, certificate); - } + if (m_certificate != null) + return new DerTaggedObject(true, 0, m_certificate); - return new DerTaggedObject(true, 1, encryptedCert); + return new DerTaggedObject(true, 1, m_encryptedCert); } } } diff --git a/crypto/src/asn1/cmp/CertRepMessage.cs b/crypto/src/asn1/cmp/CertRepMessage.cs index d24dd963b..696cfde47 100644 --- a/crypto/src/asn1/cmp/CertRepMessage.cs +++ b/crypto/src/asn1/cmp/CertRepMessage.cs @@ -7,8 +7,19 @@ namespace Org.BouncyCastle.Asn1.Cmp public class CertRepMessage : Asn1Encodable { - private readonly Asn1Sequence caPubs; - private readonly Asn1Sequence response; + public static CertRepMessage GetInstance(object obj) + { + if (obj is CertRepMessage certRepMessage) + return certRepMessage; + + if (obj != null) + return new CertRepMessage(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private readonly Asn1Sequence m_caPubs; + private readonly Asn1Sequence m_response; private CertRepMessage(Asn1Sequence seq) { @@ -16,57 +27,33 @@ namespace Org.BouncyCastle.Asn1.Cmp if (seq.Count > 1) { - caPubs = Asn1Sequence.GetInstance((Asn1TaggedObject)seq[index++], true); + m_caPubs = Asn1Sequence.GetInstance((Asn1TaggedObject)seq[index++], true); } - response = Asn1Sequence.GetInstance(seq[index]); - } - - public static CertRepMessage GetInstance(object obj) - { - if (obj is CertRepMessage) - return (CertRepMessage)obj; - - if (obj is Asn1Sequence) - return new CertRepMessage((Asn1Sequence)obj); - - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + m_response = Asn1Sequence.GetInstance(seq[index]); } public CertRepMessage(CmpCertificate[] caPubs, CertResponse[] response) { if (response == null) - throw new ArgumentNullException("response"); + throw new ArgumentNullException(nameof(response)); if (caPubs != null) { - this.caPubs = new DerSequence(caPubs); + m_caPubs = new DerSequence(caPubs); } - this.response = new DerSequence(response); + m_response = new DerSequence(response); } public virtual CmpCertificate[] GetCAPubs() { - if (caPubs == null) - return null; - - CmpCertificate[] results = new CmpCertificate[caPubs.Count]; - for (int i = 0; i != results.Length; ++i) - { - results[i] = CmpCertificate.GetInstance(caPubs[i]); - } - return results; + return m_caPubs == null ? null : m_caPubs.MapElements(CmpCertificate.GetInstance); } public virtual CertResponse[] GetResponse() { - CertResponse[] results = new CertResponse[response.Count]; - for (int i = 0; i != results.Length; ++i) - { - results[i] = CertResponse.GetInstance(response[i]); - } - return results; + return m_response.MapElements(CertResponse.GetInstance); } /** @@ -81,9 +68,9 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(); - v.AddOptionalTagged(true, 1, caPubs); - v.Add(response); + Asn1EncodableVector v = new Asn1EncodableVector(2); + v.AddOptionalTagged(true, 1, m_caPubs); + v.Add(m_response); return new DerSequence(v); } } diff --git a/crypto/src/asn1/cmp/CertReqTemplateContent.cs b/crypto/src/asn1/cmp/CertReqTemplateContent.cs new file mode 100644 index 000000000..c25c71ad1 --- /dev/null +++ b/crypto/src/asn1/cmp/CertReqTemplateContent.cs @@ -0,0 +1,67 @@ +using System; + +using Org.BouncyCastle.Asn1.Crmf; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + /** + * GenMsg: {id-it 19}, < absent > + * GenRep: {id-it 19}, CertReqTemplateContent | < absent > + * <p> + * CertReqTemplateValue ::= CertReqTemplateContent + * </p><p> + * CertReqTemplateContent ::= SEQUENCE { + * certTemplate CertTemplate, + * keySpec Controls OPTIONAL } + * </p><p> + * Controls ::= SEQUENCE SIZE (1..MAX) OF AttributeTypeAndValue + * </p> + */ + public class CertReqTemplateContent + : Asn1Encodable + { + public static CertReqTemplateContent GetInstance(object obj) + { + if (obj is CertReqTemplateContent certReqTemplateContent) + return certReqTemplateContent; + + if (obj != null) + return new CertReqTemplateContent(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private readonly CertTemplate m_certTemplate; + private readonly Asn1Sequence m_keySpec; + + private CertReqTemplateContent(Asn1Sequence seq) + { + if (seq.Count != 1 && seq.Count != 2) + throw new ArgumentException("expected sequence size of 1 or 2"); + + m_certTemplate = CertTemplate.GetInstance(seq[0]); + + if (seq.Count > 1) + { + m_keySpec = Asn1Sequence.GetInstance(seq[1]); + } + } + + public CertReqTemplateContent(CertTemplate certTemplate, Asn1Sequence keySpec) + { + m_certTemplate = certTemplate; + m_keySpec = keySpec; + } + + public virtual CertTemplate CertTemplate => m_certTemplate; + + public virtual Asn1Sequence KeySpec => m_keySpec; + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(m_certTemplate); + v.AddOptional(m_keySpec); + return new DerSequence(v); + } + } +} diff --git a/crypto/src/asn1/cmp/CertResponse.cs b/crypto/src/asn1/cmp/CertResponse.cs index 843fd9299..72a44c93e 100644 --- a/crypto/src/asn1/cmp/CertResponse.cs +++ b/crypto/src/asn1/cmp/CertResponse.cs @@ -1,21 +1,30 @@ using System; -using Org.BouncyCastle.Utilities; - namespace Org.BouncyCastle.Asn1.Cmp { public class CertResponse : Asn1Encodable { - private readonly DerInteger certReqId; - private readonly PkiStatusInfo status; - private readonly CertifiedKeyPair certifiedKeyPair; - private readonly Asn1OctetString rspInfo; + public static CertResponse GetInstance(object obj) + { + if (obj is CertResponse certResponse) + return certResponse; + + if (obj != null) + return new CertResponse(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private readonly DerInteger m_certReqId; + private readonly PkiStatusInfo m_status; + private readonly CertifiedKeyPair m_certifiedKeyPair; + private readonly Asn1OctetString m_rspInfo; private CertResponse(Asn1Sequence seq) { - certReqId = DerInteger.GetInstance(seq[0]); - status = PkiStatusInfo.GetInstance(seq[1]); + m_certReqId = DerInteger.GetInstance(seq[0]); + m_status = PkiStatusInfo.GetInstance(seq[1]); if (seq.Count >= 3) { @@ -24,71 +33,46 @@ namespace Org.BouncyCastle.Asn1.Cmp Asn1Encodable o = seq[2]; if (o is Asn1OctetString) { - rspInfo = Asn1OctetString.GetInstance(o); + m_rspInfo = Asn1OctetString.GetInstance(o); } else { - certifiedKeyPair = CertifiedKeyPair.GetInstance(o); + m_certifiedKeyPair = CertifiedKeyPair.GetInstance(o); } } else { - certifiedKeyPair = CertifiedKeyPair.GetInstance(seq[2]); - rspInfo = Asn1OctetString.GetInstance(seq[3]); + m_certifiedKeyPair = CertifiedKeyPair.GetInstance(seq[2]); + m_rspInfo = Asn1OctetString.GetInstance(seq[3]); } } } - public static CertResponse GetInstance(object obj) - { - if (obj is CertResponse) - return (CertResponse)obj; - - if (obj is Asn1Sequence) - return new CertResponse((Asn1Sequence)obj); - - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); - } - - public CertResponse( - DerInteger certReqId, - PkiStatusInfo status) + public CertResponse(DerInteger certReqId, PkiStatusInfo status) : this(certReqId, status, null, null) { } - public CertResponse( - DerInteger certReqId, - PkiStatusInfo status, - CertifiedKeyPair certifiedKeyPair, - Asn1OctetString rspInfo) - { - if (certReqId == null) - throw new ArgumentNullException("certReqId"); + public CertResponse(DerInteger certReqId, PkiStatusInfo status, CertifiedKeyPair certifiedKeyPair, + Asn1OctetString rspInfo) + { + if (certReqId == null) + throw new ArgumentNullException(nameof(certReqId)); if (status == null) - throw new ArgumentNullException("status"); + throw new ArgumentNullException(nameof(status)); - this.certReqId = certReqId; - this.status = status; - this.certifiedKeyPair = certifiedKeyPair; - this.rspInfo = rspInfo; + m_certReqId = certReqId; + m_status = status; + m_certifiedKeyPair = certifiedKeyPair; + m_rspInfo = rspInfo; } - public virtual DerInteger CertReqID - { - get { return certReqId; } - } + public virtual DerInteger CertReqID => m_certReqId; - public virtual PkiStatusInfo Status - { - get { return status; } - } + public virtual PkiStatusInfo Status => m_status; - public virtual CertifiedKeyPair CertifiedKeyPair - { - get { return certifiedKeyPair; } - } + public virtual CertifiedKeyPair CertifiedKeyPair => m_certifiedKeyPair; /** * <pre> @@ -108,8 +92,8 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(certReqId, status); - v.AddOptional(certifiedKeyPair, rspInfo); + Asn1EncodableVector v = new Asn1EncodableVector(m_certReqId, m_status); + v.AddOptional(m_certifiedKeyPair, m_rspInfo); return new DerSequence(v); } } diff --git a/crypto/src/asn1/cmp/CertStatus.cs b/crypto/src/asn1/cmp/CertStatus.cs index d437b57b2..6eb36c6fb 100644 --- a/crypto/src/asn1/cmp/CertStatus.cs +++ b/crypto/src/asn1/cmp/CertStatus.cs @@ -1,84 +1,102 @@ using System; +using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Math; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1.Cmp { public class CertStatus : Asn1Encodable { - private readonly Asn1OctetString certHash; - private readonly DerInteger certReqId; - private readonly PkiStatusInfo statusInfo; + public static CertStatus GetInstance(object obj) + { + if (obj is CertStatus certStatus) + return certStatus; - private CertStatus(Asn1Sequence seq) + if (obj != null) + return new CertStatus(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private readonly Asn1OctetString m_certHash; + private readonly DerInteger m_certReqID; + private readonly PkiStatusInfo m_statusInfo; + private readonly AlgorithmIdentifier m_hashAlg; + + private CertStatus(Asn1Sequence seq) { - certHash = Asn1OctetString.GetInstance(seq[0]); - certReqId = DerInteger.GetInstance(seq[1]); + m_certHash = Asn1OctetString.GetInstance(seq[0]); + m_certReqID = DerInteger.GetInstance(seq[1]); if (seq.Count > 2) { - statusInfo = PkiStatusInfo.GetInstance(seq[2]); + for (int t = 2; t < seq.Count; t++) + { + Asn1Object p = seq[t].ToAsn1Object(); + if (p is Asn1Sequence s) + { + m_statusInfo = PkiStatusInfo.GetInstance(s); + } + if (p is Asn1TaggedObject dto) + { + if (dto.TagNo != 0) + throw new ArgumentException("unknown tag " + dto.TagNo); + + m_hashAlg = AlgorithmIdentifier.GetInstance(dto, true); + } + } } } - public CertStatus(byte[] certHash, BigInteger certReqId) + public CertStatus(byte[] certHash, BigInteger certReqID) { - this.certHash = new DerOctetString(certHash); - this.certReqId = new DerInteger(certReqId); + m_certHash = new DerOctetString(certHash); + m_certReqID = new DerInteger(certReqID); } - public CertStatus(byte[] certHash, BigInteger certReqId, PkiStatusInfo statusInfo) + public CertStatus(byte[] certHash, BigInteger certReqID, PkiStatusInfo statusInfo) { - this.certHash = new DerOctetString(certHash); - this.certReqId = new DerInteger(certReqId); - this.statusInfo = statusInfo; + m_certHash = new DerOctetString(certHash); + m_certReqID = new DerInteger(certReqID); + m_statusInfo = statusInfo; } - public static CertStatus GetInstance(object obj) - { - if (obj is CertStatus) - return (CertStatus)obj; + public CertStatus(byte[] certHash, BigInteger certReqID, PkiStatusInfo statusInfo, AlgorithmIdentifier hashAlg) + { + m_certHash = new DerOctetString(certHash); + m_certReqID = new DerInteger(certReqID); + m_statusInfo = statusInfo; + m_hashAlg = hashAlg; + } - if (obj is Asn1Sequence) - return new CertStatus((Asn1Sequence)obj); + public virtual Asn1OctetString CertHash => m_certHash; - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); - } + public virtual DerInteger CertReqID => m_certReqID; - public virtual Asn1OctetString CertHash - { - get { return certHash; } - } - - public virtual DerInteger CertReqID - { - get { return certReqId; } - } + public virtual PkiStatusInfo StatusInfo => m_statusInfo; - public virtual PkiStatusInfo StatusInfo - { - get { return statusInfo; } - } + public virtual AlgorithmIdentifier HashAlg => m_hashAlg; - /** - * <pre> - * CertStatus ::= SEQUENCE { - * certHash OCTET STRING, - * -- the hash of the certificate, using the same hash algorithm - * -- as is used to create and verify the certificate signature - * certReqId INTEGER, - * -- to match this confirmation with the corresponding req/rep - * statusInfo PKIStatusInfo OPTIONAL - * } - * </pre> - * @return a basic ASN.1 object representation. - */ - public override Asn1Object ToAsn1Object() + /** + * <pre> + * + * CertStatus ::= SEQUENCE { + * certHash OCTET STRING, + * certReqId INTEGER, + * statusInfo PKIStatusInfo OPTIONAL, + * hashAlg [0] AlgorithmIdentifier{DIGEST-ALGORITHM, {...}} OPTIONAL + * } + * + * </pre> + * + * @return a basic ASN.1 object representation. + */ + public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(certHash, certReqId); - v.AddOptional(statusInfo); + Asn1EncodableVector v = new Asn1EncodableVector(m_certHash, m_certReqID); + v.AddOptional(m_statusInfo); + v.AddOptionalTagged(true, 0, m_hashAlg); return new DerSequence(v); } } diff --git a/crypto/src/asn1/cmp/CertifiedKeyPair.cs b/crypto/src/asn1/cmp/CertifiedKeyPair.cs index 0b1c5d44d..ec60ce965 100644 --- a/crypto/src/asn1/cmp/CertifiedKeyPair.cs +++ b/crypto/src/asn1/cmp/CertifiedKeyPair.cs @@ -1,20 +1,30 @@ using System; using Org.BouncyCastle.Asn1.Crmf; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1.Cmp { public class CertifiedKeyPair : Asn1Encodable { - private readonly CertOrEncCert certOrEncCert; - private readonly EncryptedValue privateKey; - private readonly PkiPublicationInfo publicationInfo; + public static CertifiedKeyPair GetInstance(object obj) + { + if (obj is CertifiedKeyPair certifiedKeyPair) + return certifiedKeyPair; - private CertifiedKeyPair(Asn1Sequence seq) + if (obj != null) + return new CertifiedKeyPair(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private readonly CertOrEncCert m_certOrEncCert; + private readonly EncryptedKey m_privateKey; + private readonly PkiPublicationInfo m_publicationInfo; + + private CertifiedKeyPair(Asn1Sequence seq) { - certOrEncCert = CertOrEncCert.GetInstance(seq[0]); + m_certOrEncCert = CertOrEncCert.GetInstance(seq[0]); if (seq.Count >= 2) { @@ -23,66 +33,48 @@ namespace Org.BouncyCastle.Asn1.Cmp Asn1TaggedObject tagged = Asn1TaggedObject.GetInstance(seq[1]); if (tagged.TagNo == 0) { - privateKey = EncryptedValue.GetInstance(tagged.GetObject()); + m_privateKey = EncryptedKey.GetInstance(tagged.GetObject()); } else { - publicationInfo = PkiPublicationInfo.GetInstance(tagged.GetObject()); + m_publicationInfo = PkiPublicationInfo.GetInstance(tagged.GetObject()); } } else { - privateKey = EncryptedValue.GetInstance(Asn1TaggedObject.GetInstance(seq[1])); - publicationInfo = PkiPublicationInfo.GetInstance(Asn1TaggedObject.GetInstance(seq[2])); + m_privateKey = EncryptedKey.GetInstance(Asn1TaggedObject.GetInstance(seq[1]).GetObject()); + m_publicationInfo = PkiPublicationInfo.GetInstance(Asn1TaggedObject.GetInstance(seq[2]).GetObject()); } } } - public static CertifiedKeyPair GetInstance(object obj) + public CertifiedKeyPair(CertOrEncCert certOrEncCert) + : this(certOrEncCert, (EncryptedKey)null, null) { - if (obj is CertifiedKeyPair) - return (CertifiedKeyPair)obj; - - if (obj is Asn1Sequence) - return new CertifiedKeyPair((Asn1Sequence)obj); - - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); } - public CertifiedKeyPair( - CertOrEncCert certOrEncCert) - : this(certOrEncCert, null, null) - { - } + public CertifiedKeyPair(CertOrEncCert certOrEncCert, EncryptedValue privateKey, + PkiPublicationInfo publicationInfo) + : this(certOrEncCert, privateKey == null ? null : new EncryptedKey(privateKey), publicationInfo) + { + } - public CertifiedKeyPair( - CertOrEncCert certOrEncCert, - EncryptedValue privateKey, - PkiPublicationInfo publicationInfo - ) - { + public CertifiedKeyPair(CertOrEncCert certOrEncCert, EncryptedKey privateKey, + PkiPublicationInfo publicationInfo) + { if (certOrEncCert == null) - throw new ArgumentNullException("certOrEncCert"); + throw new ArgumentNullException(nameof(certOrEncCert)); - this.certOrEncCert = certOrEncCert; - this.privateKey = privateKey; - this.publicationInfo = publicationInfo; - } + m_certOrEncCert = certOrEncCert; + m_privateKey = privateKey; + m_publicationInfo = publicationInfo; + } - public virtual CertOrEncCert CertOrEncCert - { - get { return certOrEncCert; } - } + public virtual CertOrEncCert CertOrEncCert => m_certOrEncCert; - public virtual EncryptedValue PrivateKey - { - get { return privateKey; } - } + public virtual EncryptedKey PrivateKey => m_privateKey; - public virtual PkiPublicationInfo PublicationInfo - { - get { return publicationInfo; } - } + public virtual PkiPublicationInfo PublicationInfo => m_publicationInfo; /** * <pre> @@ -97,9 +89,9 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(certOrEncCert); - v.AddOptionalTagged(true, 0, privateKey); - v.AddOptionalTagged(true, 1, publicationInfo); + Asn1EncodableVector v = new Asn1EncodableVector(m_certOrEncCert); + v.AddOptionalTagged(true, 0, m_privateKey); + v.AddOptionalTagged(true, 1, m_publicationInfo); return new DerSequence(v); } } diff --git a/crypto/src/asn1/cmp/Challenge.cs b/crypto/src/asn1/cmp/Challenge.cs index 016c082e2..ca3d06339 100644 --- a/crypto/src/asn1/cmp/Challenge.cs +++ b/crypto/src/asn1/cmp/Challenge.cs @@ -1,16 +1,52 @@ using System; using Org.BouncyCastle.Asn1.X509; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1.Cmp { - public class Challenge + /** + * <pre> + * Challenge ::= SEQUENCE { + * owf AlgorithmIdentifier OPTIONAL, + * + * -- MUST be present in the first Challenge; MAY be omitted in + * -- any subsequent Challenge in POPODecKeyChallContent (if + * -- omitted, then the owf used in the immediately preceding + * -- Challenge is to be used). + * + * witness OCTET STRING, + * -- the result of applying the one-way function (owf) to a + * -- randomly-generated INTEGER, A. [Note that a different + * -- INTEGER MUST be used for each Challenge.] + * challenge OCTET STRING + * -- the encryption (under the public key for which the cert. + * -- request is being made) of Rand, where Rand is specified as + * -- Rand ::= SEQUENCE { + * -- int INTEGER, + * -- - the randomly-generated INTEGER A (above) + * -- sender GeneralName + * -- - the sender's name (as included in PKIHeader) + * -- } + * } + * </pre> + */ + public class Challenge : Asn1Encodable { - private readonly AlgorithmIdentifier owf; - private readonly Asn1OctetString witness; - private readonly Asn1OctetString challenge; + public static Challenge GetInstance(object obj) + { + if (obj is Challenge challenge) + return challenge; + + if (obj != null) + return new Challenge(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private readonly AlgorithmIdentifier m_owf; + private readonly Asn1OctetString m_witness; + private readonly Asn1OctetString m_challenge; private Challenge(Asn1Sequence seq) { @@ -18,30 +54,32 @@ namespace Org.BouncyCastle.Asn1.Cmp if (seq.Count == 3) { - owf = AlgorithmIdentifier.GetInstance(seq[index++]); + m_owf = AlgorithmIdentifier.GetInstance(seq[index++]); } - witness = Asn1OctetString.GetInstance(seq[index++]); - challenge = Asn1OctetString.GetInstance(seq[index]); + m_witness = Asn1OctetString.GetInstance(seq[index++]); + m_challenge = Asn1OctetString.GetInstance(seq[index]); } - public static Challenge GetInstance(object obj) - { - if (obj is Challenge) - return (Challenge)obj; + public Challenge(byte[] witness, byte[] challenge) + : this(null, witness, challenge) + { + } - if (obj is Asn1Sequence) - return new Challenge((Asn1Sequence)obj); + public Challenge(AlgorithmIdentifier owf, byte[] witness, byte[] challenge) + { + m_owf = owf; + m_witness = new DerOctetString(witness); + m_challenge = new DerOctetString(challenge); + } - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); - } + public virtual AlgorithmIdentifier Owf => m_owf; - public virtual AlgorithmIdentifier Owf - { - get { return owf; } - } + public virtual Asn1OctetString Witness => m_witness; + + public virtual Asn1OctetString ChallengeValue => m_challenge; - /** + /** * <pre> * Challenge ::= SEQUENCE { * owf AlgorithmIdentifier OPTIONAL, @@ -68,12 +106,57 @@ namespace Org.BouncyCastle.Asn1.Cmp * </pre> * @return a basic ASN.1 object representation. */ - public override Asn1Object ToAsn1Object() + public override Asn1Object ToAsn1Object() { Asn1EncodableVector v = new Asn1EncodableVector(); - v.AddOptional(owf); - v.Add(witness, challenge); + v.AddOptional(m_owf); + v.Add(m_witness, m_challenge); return new DerSequence(v); } + + /** + * Rand is the inner type + */ + public class Rand + : Asn1Encodable + { + public static Rand GetInstance(object obj) + { + if (obj is Rand rand) + return rand; + + if (obj != null) + return new Rand(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private readonly DerInteger m_intVal; + private readonly GeneralName m_sender; + + public Rand(DerInteger intVal, GeneralName sender) + { + m_intVal = intVal; + m_sender = sender; + } + + public Rand(Asn1Sequence seq) + { + if (seq.Count != 2) + throw new ArgumentException("expected sequence size of 2"); + + m_intVal = DerInteger.GetInstance(seq[0]); + m_sender = GeneralName.GetInstance(seq[1]); + } + + public virtual DerInteger IntVal => m_intVal; + + public virtual GeneralName Sender => m_sender; + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(m_intVal, m_sender); + } + } } } diff --git a/crypto/src/asn1/cmp/CmpCertificate.cs b/crypto/src/asn1/cmp/CmpCertificate.cs index 33356b486..af433ec4d 100644 --- a/crypto/src/asn1/cmp/CmpCertificate.cs +++ b/crypto/src/asn1/cmp/CmpCertificate.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Utilities; @@ -8,54 +9,84 @@ namespace Org.BouncyCastle.Asn1.Cmp public class CmpCertificate : Asn1Encodable, IAsn1Choice { - private readonly X509CertificateStructure x509v3PKCert; - private readonly AttributeCertificate x509v2AttrCert; - - /** - * Note: the addition of attribute certificates is a BC extension. - */ - public CmpCertificate(AttributeCertificate x509v2AttrCert) + public static CmpCertificate GetInstance(object obj) { - this.x509v2AttrCert = x509v2AttrCert; - } + // TODO[cmp] Review this whole metho - public CmpCertificate(X509CertificateStructure x509v3PKCert) - { - if (x509v3PKCert.Version != 3) - throw new ArgumentException("only version 3 certificates allowed", "x509v3PKCert"); + if (obj == null) + return null; - this.x509v3PKCert = x509v3PKCert; - } + if (obj is CmpCertificate cmpCertificate) + return cmpCertificate; - public static CmpCertificate GetInstance(object obj) - { - if (obj is CmpCertificate) - return (CmpCertificate)obj; + if (obj is byte[] bs) + { + try + { + obj = Asn1Object.FromByteArray(bs); + } + catch (IOException) + { + throw new ArgumentException("Invalid encoding in CmpCertificate"); + } + } if (obj is Asn1Sequence) return new CmpCertificate(X509CertificateStructure.GetInstance(obj)); - if (obj is Asn1TaggedObject) - return new CmpCertificate(AttributeCertificate.GetInstance(((Asn1TaggedObject)obj).GetObject())); + if (obj is Asn1TaggedObject taggedObject) + return new CmpCertificate(taggedObject.TagNo, taggedObject.GetObject()); - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), nameof(obj)); } - public virtual bool IsX509v3PKCert + public static CmpCertificate GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) { - get { return x509v3PKCert != null; } + // TODO[cmp] + if (taggedObject == null) + return null; + + if (!declaredExplicit) + throw new ArgumentException("tag must be explicit"); + + // TODO[cmp] + return GetInstance(taggedObject.GetObject()); } - public virtual X509CertificateStructure X509v3PKCert + private readonly X509CertificateStructure m_x509v3PKCert; + + private readonly int m_otherTagValue; + private readonly Asn1Encodable m_otherCert; + + /** + * Note: the addition of other certificates is a BC extension. If you use this constructor they + * will be added with an explicit tag value of type. + * + * @param type the type of the certificate (used as a tag value). + * @param otherCert the object representing the certificate + */ + public CmpCertificate(int type, Asn1Encodable otherCert) { - get { return x509v3PKCert; } + m_otherTagValue = type; + m_otherCert = otherCert; } - public virtual AttributeCertificate X509v2AttrCert + public CmpCertificate(X509CertificateStructure x509v3PKCert) { - get { return x509v2AttrCert; } + if (x509v3PKCert.Version != 3) + throw new ArgumentException("only version 3 certificates allowed", nameof(x509v3PKCert)); + + m_x509v3PKCert = x509v3PKCert; } + public virtual bool IsX509v3PKCert => m_x509v3PKCert != null; + + public virtual X509CertificateStructure X509v3PKCert => m_x509v3PKCert; + + public virtual int OtherCertTag => m_otherTagValue; + + public virtual Asn1Encodable OtherCert => m_otherCert; + /** * <pre> * CMPCertificate ::= CHOICE { @@ -69,13 +100,13 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - if (x509v2AttrCert != null) + if (m_otherCert != null) { // explicit following CMP conventions - return new DerTaggedObject(true, 1, x509v2AttrCert); + return new DerTaggedObject(true, m_otherTagValue, m_otherCert); } - return x509v3PKCert.ToAsn1Object(); + return m_x509v3PKCert.ToAsn1Object(); } } } diff --git a/crypto/src/asn1/cmp/CmpObjectIdentifiers.cs b/crypto/src/asn1/cmp/CmpObjectIdentifiers.cs index 7e8274175..1b3227c47 100644 --- a/crypto/src/asn1/cmp/CmpObjectIdentifiers.cs +++ b/crypto/src/asn1/cmp/CmpObjectIdentifiers.cs @@ -2,105 +2,257 @@ using System; namespace Org.BouncyCastle.Asn1.Cmp { - public abstract class CmpObjectIdentifiers + public static class CmpObjectIdentifiers { - // RFC 4210 - - // id-PasswordBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 13} - public static readonly DerObjectIdentifier passwordBasedMac = new DerObjectIdentifier("1.2.840.113533.7.66.13"); - - // id-DHBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 30} - public static readonly DerObjectIdentifier dhBasedMac = new DerObjectIdentifier("1.2.840.113533.7.66.30"); - - // Example InfoTypeAndValue contents include, but are not limited - // to, the following (un-comment in this ASN.1 module and use as - // appropriate for a given environment): - // - // id-it-caProtEncCert OBJECT IDENTIFIER ::= {id-it 1} - // CAProtEncCertValue ::= CMPCertificate - // id-it-signKeyPairTypes OBJECT IDENTIFIER ::= {id-it 2} - // SignKeyPairTypesValue ::= SEQUENCE OF AlgorithmIdentifier - // id-it-encKeyPairTypes OBJECT IDENTIFIER ::= {id-it 3} - // EncKeyPairTypesValue ::= SEQUENCE OF AlgorithmIdentifier - // id-it-preferredSymmAlg OBJECT IDENTIFIER ::= {id-it 4} - // PreferredSymmAlgValue ::= AlgorithmIdentifier - // id-it-caKeyUpdateInfo OBJECT IDENTIFIER ::= {id-it 5} - // CAKeyUpdateInfoValue ::= CAKeyUpdAnnContent - // id-it-currentCRL OBJECT IDENTIFIER ::= {id-it 6} - // CurrentCRLValue ::= CertificateList - // id-it-unsupportedOIDs OBJECT IDENTIFIER ::= {id-it 7} - // UnsupportedOIDsValue ::= SEQUENCE OF OBJECT IDENTIFIER - // id-it-keyPairParamReq OBJECT IDENTIFIER ::= {id-it 10} - // KeyPairParamReqValue ::= OBJECT IDENTIFIER - // id-it-keyPairParamRep OBJECT IDENTIFIER ::= {id-it 11} - // KeyPairParamRepValue ::= AlgorithmIdentifer - // id-it-revPassphrase OBJECT IDENTIFIER ::= {id-it 12} - // RevPassphraseValue ::= EncryptedValue - // id-it-implicitConfirm OBJECT IDENTIFIER ::= {id-it 13} - // ImplicitConfirmValue ::= NULL - // id-it-confirmWaitTime OBJECT IDENTIFIER ::= {id-it 14} - // ConfirmWaitTimeValue ::= GeneralizedTime - // id-it-origPKIMessage OBJECT IDENTIFIER ::= {id-it 15} - // OrigPKIMessageValue ::= PKIMessages - // id-it-suppLangTags OBJECT IDENTIFIER ::= {id-it 16} - // SuppLangTagsValue ::= SEQUENCE OF UTF8String - // - // where - // - // id-pkix OBJECT IDENTIFIER ::= { - // iso(1) identified-organization(3) - // dod(6) internet(1) security(5) mechanisms(5) pkix(7)} - // and - // id-it OBJECT IDENTIFIER ::= {id-pkix 4} - public static readonly DerObjectIdentifier it_caProtEncCert = new DerObjectIdentifier("1.3.6.1.5.5.7.4.1"); - public static readonly DerObjectIdentifier it_signKeyPairTypes = new DerObjectIdentifier("1.3.6.1.5.5.7.4.2"); - public static readonly DerObjectIdentifier it_encKeyPairTypes = new DerObjectIdentifier("1.3.6.1.5.5.7.4.3"); - public static readonly DerObjectIdentifier it_preferredSymAlg = new DerObjectIdentifier("1.3.6.1.5.5.7.4.4"); - public static readonly DerObjectIdentifier it_caKeyUpdateInfo = new DerObjectIdentifier("1.3.6.1.5.5.7.4.5"); - public static readonly DerObjectIdentifier it_currentCRL = new DerObjectIdentifier("1.3.6.1.5.5.7.4.6"); - public static readonly DerObjectIdentifier it_unsupportedOIDs = new DerObjectIdentifier("1.3.6.1.5.5.7.4.7"); - public static readonly DerObjectIdentifier it_keyPairParamReq = new DerObjectIdentifier("1.3.6.1.5.5.7.4.10"); - public static readonly DerObjectIdentifier it_keyPairParamRep = new DerObjectIdentifier("1.3.6.1.5.5.7.4.11"); - public static readonly DerObjectIdentifier it_revPassphrase = new DerObjectIdentifier("1.3.6.1.5.5.7.4.12"); - public static readonly DerObjectIdentifier it_implicitConfirm = new DerObjectIdentifier("1.3.6.1.5.5.7.4.13"); - public static readonly DerObjectIdentifier it_confirmWaitTime = new DerObjectIdentifier("1.3.6.1.5.5.7.4.14"); - public static readonly DerObjectIdentifier it_origPKIMessage = new DerObjectIdentifier("1.3.6.1.5.5.7.4.15"); - public static readonly DerObjectIdentifier it_suppLangTags = new DerObjectIdentifier("1.3.6.1.5.5.7.4.16"); - - // RFC 4211 - - // id-pkix OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) - // dod(6) internet(1) security(5) mechanisms(5) pkix(7) } - // - // arc for Internet X.509 PKI protocols and their components - // id-pkip OBJECT IDENTIFIER :: { id-pkix pkip(5) } - // - // arc for Registration Controls in CRMF - // id-regCtrl OBJECT IDENTIFIER ::= { id-pkip regCtrl(1) } - // - // arc for Registration Info in CRMF - // id-regInfo OBJECT IDENTIFIER ::= { id-pkip id-regInfo(2) } - - public static readonly DerObjectIdentifier regCtrl_regToken = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.1"); - public static readonly DerObjectIdentifier regCtrl_authenticator = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.2"); - public static readonly DerObjectIdentifier regCtrl_pkiPublicationInfo = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.3"); - public static readonly DerObjectIdentifier regCtrl_pkiArchiveOptions = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.4"); - public static readonly DerObjectIdentifier regCtrl_oldCertID = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.5"); - public static readonly DerObjectIdentifier regCtrl_protocolEncrKey = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.6"); - - // From RFC4210: - // id-regCtrl-altCertTemplate OBJECT IDENTIFIER ::= {id-regCtrl 7} - public static readonly DerObjectIdentifier regCtrl_altCertTemplate = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.7"); - - public static readonly DerObjectIdentifier regInfo_utf8Pairs = new DerObjectIdentifier("1.3.6.1.5.5.7.5.2.1"); - public static readonly DerObjectIdentifier regInfo_certReq = new DerObjectIdentifier("1.3.6.1.5.5.7.5.2.2"); - - // id-smime OBJECT IDENTIFIER ::= { iso(1) member-body(2) - // us(840) rsadsi(113549) pkcs(1) pkcs9(9) 16 } - // - // id-ct OBJECT IDENTIFIER ::= { id-smime 1 } -- content types - // - // id-ct-encKeyWithID OBJECT IDENTIFIER ::= {id-ct 21} - public static readonly DerObjectIdentifier ct_encKeyWithID = new DerObjectIdentifier("1.2.840.113549.1.9.16.1.21"); + // RFC 4210 + + /** + * id-PasswordBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 13} + */ + public static readonly DerObjectIdentifier passwordBasedMac = new DerObjectIdentifier("1.2.840.113533.7.66.13"); + + /** + * id-DHBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 30} + */ + public static readonly DerObjectIdentifier dhBasedMac = new DerObjectIdentifier("1.2.840.113533.7.66.30"); + + // Example InfoTypeAndValue contents include, but are not limited + // to, the following (un-comment in this ASN.1 module and use as + // appropriate for a given environment): + // + // id-it-caProtEncCert OBJECT IDENTIFIER ::= {id-it 1} + // CAProtEncCertValue ::= CMPCertificate + // id-it-signKeyPairTypes OBJECT IDENTIFIER ::= {id-it 2} + // SignKeyPairTypesValue ::= SEQUENCE OF AlgorithmIdentifier + // id-it-encKeyPairTypes OBJECT IDENTIFIER ::= {id-it 3} + // EncKeyPairTypesValue ::= SEQUENCE OF AlgorithmIdentifier + // id-it-preferredSymmAlg OBJECT IDENTIFIER ::= {id-it 4} + // PreferredSymmAlgValue ::= AlgorithmIdentifier + // id-it-caKeyUpdateInfo OBJECT IDENTIFIER ::= {id-it 5} + // CAKeyUpdateInfoValue ::= CAKeyUpdAnnContent + // id-it-currentCRL OBJECT IDENTIFIER ::= {id-it 6} + // CurrentCRLValue ::= CertificateList + // id-it-unsupportedOIDs OBJECT IDENTIFIER ::= {id-it 7} + // UnsupportedOIDsValue ::= SEQUENCE OF OBJECT IDENTIFIER + // id-it-keyPairParamReq OBJECT IDENTIFIER ::= {id-it 10} + // KeyPairParamReqValue ::= OBJECT IDENTIFIER + // id-it-keyPairParamRep OBJECT IDENTIFIER ::= {id-it 11} + // KeyPairParamRepValue ::= AlgorithmIdentifer + // id-it-revPassphrase OBJECT IDENTIFIER ::= {id-it 12} + // RevPassphraseValue ::= EncryptedValue + // id-it-implicitConfirm OBJECT IDENTIFIER ::= {id-it 13} + // ImplicitConfirmValue ::= NULL + // id-it-confirmWaitTime OBJECT IDENTIFIER ::= {id-it 14} + // ConfirmWaitTimeValue ::= GeneralizedTime + // id-it-origPKIMessage OBJECT IDENTIFIER ::= {id-it 15} + // OrigPKIMessageValue ::= PKIMessages + // id-it-suppLangTags OBJECT IDENTIFIER ::= {id-it 16} + // SuppLangTagsValue ::= SEQUENCE OF UTF8String + // id-it-certProfile OBJECT IDENTIFIER ::= {id-it 21} + // CertProfileValue ::= SEQUENCE SIZE (1..MAX) OF UTF8String + // where + // + // id-pkix OBJECT IDENTIFIER ::= { + // iso(1) identified-organization(3) + // dod(6) internet(1) security(5) mechanisms(5) pkix(7)} + // and + // id-it OBJECT IDENTIFIER ::= {id-pkix 4} + + /** RFC 4120: it-id: PKIX.4 = 1.3.6.1.5.5.7.4 */ + + + /** + * RFC 4120: 1.3.6.1.5.5.7.4.1 + */ + public static readonly DerObjectIdentifier it_caProtEncCert = new DerObjectIdentifier("1.3.6.1.5.5.7.4.1"); + /** + * RFC 4120: 1.3.6.1.5.5.7.4.2 + */ + public static readonly DerObjectIdentifier it_signKeyPairTypes = new DerObjectIdentifier("1.3.6.1.5.5.7.4.2"); + /** + * RFC 4120: 1.3.6.1.5.5.7.4.3 + */ + public static readonly DerObjectIdentifier it_encKeyPairTypes = new DerObjectIdentifier("1.3.6.1.5.5.7.4.3"); + /** + * RFC 4120: 1.3.6.1.5.5.7.4.4 + */ + public static readonly DerObjectIdentifier it_preferredSymAlg = new DerObjectIdentifier("1.3.6.1.5.5.7.4.4"); + /** + * RFC 4120: 1.3.6.1.5.5.7.4.5 + */ + public static readonly DerObjectIdentifier it_caKeyUpdateInfo = new DerObjectIdentifier("1.3.6.1.5.5.7.4.5"); + /** + * RFC 4120: 1.3.6.1.5.5.7.4.6 + */ + public static readonly DerObjectIdentifier it_currentCRL = new DerObjectIdentifier("1.3.6.1.5.5.7.4.6"); + /** + * RFC 4120: 1.3.6.1.5.5.7.4.7 + */ + public static readonly DerObjectIdentifier it_unsupportedOIDs = new DerObjectIdentifier("1.3.6.1.5.5.7.4.7"); + /** + * RFC 4120: 1.3.6.1.5.5.7.4.10 + */ + public static readonly DerObjectIdentifier it_keyPairParamReq = new DerObjectIdentifier("1.3.6.1.5.5.7.4.10"); + /** + * RFC 4120: 1.3.6.1.5.5.7.4.11 + */ + public static readonly DerObjectIdentifier it_keyPairParamRep = new DerObjectIdentifier("1.3.6.1.5.5.7.4.11"); + /** + * RFC 4120: 1.3.6.1.5.5.7.4.12 + */ + public static readonly DerObjectIdentifier it_revPassphrase = new DerObjectIdentifier("1.3.6.1.5.5.7.4.12"); + /** + * RFC 4120: 1.3.6.1.5.5.7.4.13 + */ + public static readonly DerObjectIdentifier it_implicitConfirm = new DerObjectIdentifier("1.3.6.1.5.5.7.4.13"); + /** + * RFC 4120: 1.3.6.1.5.5.7.4.14 + */ + public static readonly DerObjectIdentifier it_confirmWaitTime = new DerObjectIdentifier("1.3.6.1.5.5.7.4.14"); + /** + * RFC 4120: 1.3.6.1.5.5.7.4.15 + */ + public static readonly DerObjectIdentifier it_origPKIMessage = new DerObjectIdentifier("1.3.6.1.5.5.7.4.15"); + /** + * RFC 4120: 1.3.6.1.5.5.7.4.16 + */ + public static readonly DerObjectIdentifier it_suppLangTags = new DerObjectIdentifier("1.3.6.1.5.5.7.4.16"); + + /** + * Update 16, RFC 4210 + * {id-it 17} + */ + public static readonly DerObjectIdentifier id_it_caCerts = new DerObjectIdentifier("1.3.6.1.5.5.7.4.17"); + + + /** + * Update 16, RFC 4210 + * GenRep: {id-it 18}, RootCaKeyUpdateContent + */ + public static readonly DerObjectIdentifier id_it_rootCaKeyUpdate = new DerObjectIdentifier("1.3.6.1.5.5.7.4.18"); + + + /** + * Update 16, RFC 4210 + * {id-it 19} + */ + public static readonly DerObjectIdentifier id_it_certReqTemplate = new DerObjectIdentifier("1.3.6.1.5.5.7.4.19"); + + + /** + * Update 16, RFC 4210 + * GenMsg: {id-it 20}, RootCaCertValue + */ + public static readonly DerObjectIdentifier id_it_rootCaCert = new DerObjectIdentifier("1.3.6.1.5.5.7.4.20"); + + /** + * Update-16 to RFC 4210 + * id-it-certProfile OBJECT IDENTIFIER ::= {id-it 21} + */ + public static readonly DerObjectIdentifier id_it_certProfile = new DerObjectIdentifier("1.3.6.1.5.5.7.4.21"); + + public static readonly DerObjectIdentifier id_it_crlStatusList = new DerObjectIdentifier("1.3.6.1.5.5.7.4.22"); + + public static readonly DerObjectIdentifier id_it_crls = new DerObjectIdentifier("1.3.6.1.5.5.7.4.23"); + + // Not yet formally defined. + + //public static readonly DerObjectIdentifier id_it_crlStatusList = null; + //public static readonly DerObjectIdentifier id_it_crls = null; + + + // RFC 4211 + + // id-pkix OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) + // dod(6) internet(1) security(5) mechanisms(5) pkix(7) } + // + // arc for Internet X.509 PKI protocols and their components + // id-pkip OBJECT IDENTIFIER :: { id-pkix pkip(5) } + // + // arc for Registration Controls in CRMF + // id-regCtrl OBJECT IDENTIFIER ::= { id-pkip regCtrl(1) } + // + // arc for Registration Info in CRMF + // id-regInfo OBJECT IDENTIFIER ::= { id-pkip id-regInfo(2) } + + /** + * RFC 4211: it-pkip: PKIX.5 = 1.3.6.1.5.5.7.5 + */ + public static readonly DerObjectIdentifier id_pkip = new DerObjectIdentifier("1.3.6.1.5.5.7.5"); + + /** + * RFC 4211: it-regCtrl: 1.3.6.1.5.5.7.5.1 + */ + public static readonly DerObjectIdentifier id_regCtrl = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1"); + /** + * RFC 4211: it-regInfo: 1.3.6.1.5.5.7.5.2 + */ + public static readonly DerObjectIdentifier id_regInfo = new DerObjectIdentifier("1.3.6.1.5.5.7.5.2"); + + + /** + * 1.3.6.1.5.5.7.5.1.1 + */ + public static readonly DerObjectIdentifier regCtrl_regToken = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.1"); + /** + * 1.3.6.1.5.5.7.5.1.2 + */ + public static readonly DerObjectIdentifier regCtrl_authenticator = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.2"); + /** + * 1.3.6.1.5.5.7.5.1.3 + */ + public static readonly DerObjectIdentifier regCtrl_pkiPublicationInfo = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.3"); + /** + * 1.3.6.1.5.5.7.5.1.4 + */ + public static readonly DerObjectIdentifier regCtrl_pkiArchiveOptions = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.4"); + /** + * 1.3.6.1.5.5.7.5.1.5 + */ + public static readonly DerObjectIdentifier regCtrl_oldCertID = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.5"); + /** + * 1.3.6.1.5.5.7.5.1.6 + */ + public static readonly DerObjectIdentifier regCtrl_protocolEncrKey = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.6"); + + /** + * From RFC4210: + * id-regCtrl-altCertTemplate OBJECT IDENTIFIER ::= {id-regCtrl 7}; 1.3.6.1.5.5.7.1.7 + */ + public static readonly DerObjectIdentifier regCtrl_altCertTemplate = new DerObjectIdentifier("1.3.6.1.5.5.7.5.1.7"); + + /** + * RFC 4211: it-regInfo-utf8Pairs: 1.3.6.1.5.5.7.5.2.1 + */ + public static readonly DerObjectIdentifier regInfo_utf8Pairs = new DerObjectIdentifier("1.3.6.1.5.5.7.5.2.1"); + /** + * RFC 4211: it-regInfo-certReq: 1.3.6.1.5.5.7.5.2.1 + */ + public static readonly DerObjectIdentifier regInfo_certReq = new DerObjectIdentifier("1.3.6.1.5.5.7.5.2.2"); + + /** + * 1.2.840.113549.1.9.16.1.21 + * <p> + * id-ct OBJECT IDENTIFIER ::= { id-smime 1 } -- content types + * </p><p> + * id-ct-encKeyWithID OBJECT IDENTIFIER ::= {id-ct 21} + * </p> + */ + public static readonly DerObjectIdentifier ct_encKeyWithID = new DerObjectIdentifier("1.2.840.113549.1.9.16.1.21"); + + + /** + * id-regCtrl-algId OBJECT IDENTIFIER ::= { iso(1) + * identified-organization(3) dod(6) internet(1) security(5) + * mechanisms(5) pkix(7) pkip(5) regCtrl(1) 11 } + */ + public static readonly DerObjectIdentifier id_regCtrl_algId = id_pkip.Branch("1.11"); + + /** + * id-regCtrl-rsaKeyLen OBJECT IDENTIFIER ::= { iso(1) + * identified-organization(3) dod(6) internet(1) security(5) + * mechanisms(5) pkix(7) pkip(5) regCtrl(1) 12 } + */ + public static readonly DerObjectIdentifier id_regCtrl_rsaKeyLen = id_pkip.Branch("1.12"); } } diff --git a/crypto/src/asn1/cmp/CrlAnnContent.cs b/crypto/src/asn1/cmp/CrlAnnContent.cs index db8ecfa40..0da25cd0e 100644 --- a/crypto/src/asn1/cmp/CrlAnnContent.cs +++ b/crypto/src/asn1/cmp/CrlAnnContent.cs @@ -1,39 +1,36 @@ -using System; - using Org.BouncyCastle.Asn1.X509; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1.Cmp { public class CrlAnnContent : Asn1Encodable { - private readonly Asn1Sequence content; + public static CrlAnnContent GetInstance(object obj) + { + if (obj is CrlAnnContent crlAnnContent) + return crlAnnContent; - private CrlAnnContent(Asn1Sequence seq) - { - content = seq; - } + if (obj != null) + return new CrlAnnContent(Asn1Sequence.GetInstance(obj)); - public static CrlAnnContent GetInstance(object obj) - { - if (obj is CrlAnnContent) - return (CrlAnnContent)obj; + return null; + } - if (obj is Asn1Sequence) - return new CrlAnnContent((Asn1Sequence)obj); + private readonly Asn1Sequence m_content; - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + private CrlAnnContent(Asn1Sequence seq) + { + m_content = seq; } - public virtual CertificateList[] ToCertificateListArray() + public CrlAnnContent(CertificateList crl) + { + m_content = new DerSequence(crl); + } + + public virtual CertificateList[] ToCertificateListArray() { - CertificateList[] result = new CertificateList[content.Count]; - for (int i = 0; i != result.Length; ++ i) - { - result[i] = CertificateList.GetInstance(content[i]); - } - return result; + return m_content.MapElements(CertificateList.GetInstance); } /** @@ -44,7 +41,7 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - return content; + return m_content; } } } diff --git a/crypto/src/asn1/cmp/CrlSource.cs b/crypto/src/asn1/cmp/CrlSource.cs new file mode 100644 index 000000000..9e2526ec2 --- /dev/null +++ b/crypto/src/asn1/cmp/CrlSource.cs @@ -0,0 +1,72 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + /** + * GenMsg: {id-it TBD1}, SEQUENCE SIZE (1..MAX) OF CRLStatus + * GenRep: {id-it TBD2}, SEQUENCE SIZE (1..MAX) OF + * CertificateList | < absent > + * <p> + * CRLSource ::= CHOICE { + * dpn [0] DistributionPointName, + * issuer [1] GeneralNames } + * </p> + */ + public class CrlSource + : Asn1Encodable, IAsn1Choice + { + public static CrlSource GetInstance(object obj) + { + if (obj is CrlSource crlSource) + return crlSource; + + if (obj != null) + return new CrlSource(Asn1TaggedObject.GetInstance(obj)); + + return null; + } + + private readonly DistributionPointName m_dpn; + private readonly GeneralNames m_issuer; + + private CrlSource(Asn1TaggedObject taggedObject) + { + switch (taggedObject.TagNo) + { + case 0: + m_dpn = DistributionPointName.GetInstance(taggedObject, true); + m_issuer = null; + break; + case 1: + m_dpn = null; + m_issuer = GeneralNames.GetInstance(taggedObject, true); + break; + default: + throw new ArgumentException("unknown tag: " + Asn1Utilities.GetTagText(taggedObject)); + } + } + + public CrlSource(DistributionPointName dpn, GeneralNames issuer) + { + if ((dpn == null) == (issuer == null)) + throw new ArgumentException("either dpn or issuer must be set"); + + m_dpn = dpn; + m_issuer = issuer; + } + + public virtual DistributionPointName Dpn => m_dpn; + + public virtual GeneralNames Issuer => m_issuer; + + public override Asn1Object ToAsn1Object() + { + if (m_dpn != null) + return new DerTaggedObject(true, 0, m_dpn); + + return new DerTaggedObject(true, 1, m_issuer); + } + } +} diff --git a/crypto/src/asn1/cmp/CrlStatus.cs b/crypto/src/asn1/cmp/CrlStatus.cs new file mode 100644 index 000000000..5bacbbbcc --- /dev/null +++ b/crypto/src/asn1/cmp/CrlStatus.cs @@ -0,0 +1,61 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + /** + * CRLStatus ::= SEQUENCE { + * source CRLSource, + * thisUpdate Time OPTIONAL } + */ + public class CrlStatus + : Asn1Encodable + { + public static CrlStatus GetInstance(object obj) + { + if (obj is CrlStatus crlStatus) + return crlStatus; + + if (obj != null) + return new CrlStatus(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private readonly CrlSource m_source; + private readonly Time m_thisUpdate; + + private CrlStatus(Asn1Sequence sequence) + { + int count = sequence.Count; + if (count < 1 || count > 2) + throw new ArgumentException("expected sequence size of 1 or 2, got " + count); + + m_source = CrlSource.GetInstance(sequence[0]); + + if (sequence.Count == 2) + { + m_thisUpdate = Time.GetInstance(sequence[1]); + } + } + + public CrlStatus(CrlSource source, Time thisUpdate) + { + m_source = source; + m_thisUpdate = thisUpdate; + } + + public virtual CrlSource Source => m_source; + + public virtual Time ThisUpdate => m_thisUpdate; + + public override Asn1Object ToAsn1Object() + { + if (m_thisUpdate == null) + return new DerSequence(m_source); + + return new DerSequence(m_source, m_thisUpdate); + } + } +} diff --git a/crypto/src/asn1/cmp/DhbmParameter.cs b/crypto/src/asn1/cmp/DhbmParameter.cs new file mode 100644 index 000000000..aaf71f70e --- /dev/null +++ b/crypto/src/asn1/cmp/DhbmParameter.cs @@ -0,0 +1,56 @@ +using System; + +using Org.BouncyCastle.Asn1.X509; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + /** + * DHBMParameter ::= SEQUENCE { + * owf AlgorithmIdentifier, + * -- AlgId for a One-Way Function (SHA-1 recommended) + * mac AlgorithmIdentifier + * -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11], + * } -- or HMAC [RFC2104, RFC2202]) + */ + public class DhbmParameter + : Asn1Encodable + { + public static DhbmParameter GetInstance(object obj) + { + if (obj is DhbmParameter dhbmParameter) + return dhbmParameter; + + if (obj != null) + return new DhbmParameter(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private readonly AlgorithmIdentifier m_owf; + private readonly AlgorithmIdentifier m_mac; + + private DhbmParameter(Asn1Sequence sequence) + { + if (sequence.Count != 2) + throw new ArgumentException("expecting sequence size of 2"); + + m_owf = AlgorithmIdentifier.GetInstance(sequence[0]); + m_mac = AlgorithmIdentifier.GetInstance(sequence[1]); + } + + public DhbmParameter(AlgorithmIdentifier owf, AlgorithmIdentifier mac) + { + m_owf = owf; + m_mac = mac; + } + + public virtual AlgorithmIdentifier Owf => m_owf; + + public virtual AlgorithmIdentifier Mac => m_mac; + + public override Asn1Object ToAsn1Object() + { + return new DerSequence(m_owf, m_mac); + } + } +} diff --git a/crypto/src/asn1/cmp/ErrorMsgContent.cs b/crypto/src/asn1/cmp/ErrorMsgContent.cs index 5d2132bb8..fe8318aab 100644 --- a/crypto/src/asn1/cmp/ErrorMsgContent.cs +++ b/crypto/src/asn1/cmp/ErrorMsgContent.cs @@ -1,45 +1,54 @@ using System; -using Org.BouncyCastle.Utilities; - namespace Org.BouncyCastle.Asn1.Cmp { - public class ErrorMsgContent + /** + * <pre> + * ErrorMsgContent ::= SEQUENCE { + * pKIStatusInfo PKIStatusInfo, + * errorCode INTEGER OPTIONAL, + * -- implementation-specific error codes + * errorDetails PKIFreeText OPTIONAL + * -- implementation-specific error details + * } + * </pre> + */ + public class ErrorMsgContent : Asn1Encodable { - private readonly PkiStatusInfo pkiStatusInfo; - private readonly DerInteger errorCode; - private readonly PkiFreeText errorDetails; + public static ErrorMsgContent GetInstance(object obj) + { + if (obj is ErrorMsgContent errorMsgContent) + return errorMsgContent; + + if (obj != null) + return new ErrorMsgContent(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private readonly PkiStatusInfo m_pkiStatusInfo; + private readonly DerInteger m_errorCode; + private readonly PkiFreeText m_errorDetails; private ErrorMsgContent(Asn1Sequence seq) { - pkiStatusInfo = PkiStatusInfo.GetInstance(seq[0]); + m_pkiStatusInfo = PkiStatusInfo.GetInstance(seq[0]); for (int pos = 1; pos < seq.Count; ++pos) { Asn1Encodable ae = seq[pos]; if (ae is DerInteger) { - errorCode = DerInteger.GetInstance(ae); + m_errorCode = DerInteger.GetInstance(ae); } else { - errorDetails = PkiFreeText.GetInstance(ae); + m_errorDetails = PkiFreeText.GetInstance(ae); } } } - public static ErrorMsgContent GetInstance(object obj) - { - if (obj is ErrorMsgContent) - return (ErrorMsgContent)obj; - - if (obj is Asn1Sequence) - return new ErrorMsgContent((Asn1Sequence)obj); - - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); - } - public ErrorMsgContent(PkiStatusInfo pkiStatusInfo) : this(pkiStatusInfo, null, null) { @@ -51,27 +60,18 @@ namespace Org.BouncyCastle.Asn1.Cmp PkiFreeText errorDetails) { if (pkiStatusInfo == null) - throw new ArgumentNullException("pkiStatusInfo"); + throw new ArgumentNullException(nameof(pkiStatusInfo)); - this.pkiStatusInfo = pkiStatusInfo; - this.errorCode = errorCode; - this.errorDetails = errorDetails; - } - - public virtual PkiStatusInfo PkiStatusInfo - { - get { return pkiStatusInfo; } + m_pkiStatusInfo = pkiStatusInfo; + m_errorCode = errorCode; + m_errorDetails = errorDetails; } - public virtual DerInteger ErrorCode - { - get { return errorCode; } - } + public virtual PkiStatusInfo PkiStatusInfo => m_pkiStatusInfo; - public virtual PkiFreeText ErrorDetails - { - get { return errorDetails; } - } + public virtual DerInteger ErrorCode => m_errorCode; + + public virtual PkiFreeText ErrorDetails => m_errorDetails; /** * <pre> @@ -87,8 +87,8 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(pkiStatusInfo); - v.AddOptional(errorCode, errorDetails); + Asn1EncodableVector v = new Asn1EncodableVector(m_pkiStatusInfo); + v.AddOptional(m_errorCode, m_errorDetails); return new DerSequence(v); } } diff --git a/crypto/src/asn1/cmp/GenMsgContent.cs b/crypto/src/asn1/cmp/GenMsgContent.cs index f3142b5c6..b4673b76a 100644 --- a/crypto/src/asn1/cmp/GenMsgContent.cs +++ b/crypto/src/asn1/cmp/GenMsgContent.cs @@ -1,43 +1,42 @@ -using System; - -using Org.BouncyCastle.Utilities; - namespace Org.BouncyCastle.Asn1.Cmp { - public class GenMsgContent + /** + * <pre>GenMsgContent ::= SEQUENCE OF InfoTypeAndValue</pre> + */ + public class GenMsgContent : Asn1Encodable { - private readonly Asn1Sequence content; + public static GenMsgContent GetInstance(object obj) + { + if (obj is GenMsgContent genMsgContent) + return genMsgContent; - private GenMsgContent(Asn1Sequence seq) - { - content = seq; - } + if (obj != null) + return new GenMsgContent(Asn1Sequence.GetInstance(obj)); - public static GenMsgContent GetInstance(object obj) - { - if (obj is GenMsgContent) - return (GenMsgContent)obj; + return null; + } - if (obj is Asn1Sequence) - return new GenMsgContent((Asn1Sequence)obj); + private readonly Asn1Sequence m_content; - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + private GenMsgContent(Asn1Sequence seq) + { + m_content = seq; } - public GenMsgContent(params InfoTypeAndValue[] itv) + public GenMsgContent(InfoTypeAndValue itv) + { + m_content = new DerSequence(itv); + } + + public GenMsgContent(params InfoTypeAndValue[] itvs) { - content = new DerSequence(itv); + m_content = new DerSequence(itvs); } public virtual InfoTypeAndValue[] ToInfoTypeAndValueArray() { - InfoTypeAndValue[] result = new InfoTypeAndValue[content.Count]; - for (int i = 0; i != result.Length; ++i) - { - result[i] = InfoTypeAndValue.GetInstance(content[i]); - } - return result; + return m_content.MapElements(InfoTypeAndValue.GetInstance); } /** @@ -48,7 +47,7 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - return content; + return m_content; } } } diff --git a/crypto/src/asn1/cmp/GenRepContent.cs b/crypto/src/asn1/cmp/GenRepContent.cs index 3c3573e37..38f91061c 100644 --- a/crypto/src/asn1/cmp/GenRepContent.cs +++ b/crypto/src/asn1/cmp/GenRepContent.cs @@ -1,43 +1,39 @@ -using System; - -using Org.BouncyCastle.Utilities; - namespace Org.BouncyCastle.Asn1.Cmp { public class GenRepContent : Asn1Encodable { - private readonly Asn1Sequence content; + public static GenRepContent GetInstance(object obj) + { + if (obj is GenRepContent genRepContent) + return genRepContent; - private GenRepContent(Asn1Sequence seq) - { - content = seq; - } + if (obj != null) + return new GenRepContent(Asn1Sequence.GetInstance(obj)); - public static GenRepContent GetInstance(object obj) - { - if (obj is GenRepContent) - return (GenRepContent)obj; + return null; + } - if (obj is Asn1Sequence) - return new GenRepContent((Asn1Sequence)obj); + private readonly Asn1Sequence m_content; - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + private GenRepContent(Asn1Sequence seq) + { + m_content = seq; } - public GenRepContent(params InfoTypeAndValue[] itv) + public GenRepContent(InfoTypeAndValue itv) + { + m_content = new DerSequence(itv); + } + + public GenRepContent(params InfoTypeAndValue[] itvs) { - content = new DerSequence(itv); + m_content = new DerSequence(itvs); } public virtual InfoTypeAndValue[] ToInfoTypeAndValueArray() { - InfoTypeAndValue[] result = new InfoTypeAndValue[content.Count]; - for (int i = 0; i != result.Length; ++i) - { - result[i] = InfoTypeAndValue.GetInstance(content[i]); - } - return result; + return m_content.MapElements(InfoTypeAndValue.GetInstance); } /** @@ -48,7 +44,7 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - return content; + return m_content; } } } diff --git a/crypto/src/asn1/cmp/InfoTypeAndValue.cs b/crypto/src/asn1/cmp/InfoTypeAndValue.cs index 305d6e5e7..08ad68a42 100644 --- a/crypto/src/asn1/cmp/InfoTypeAndValue.cs +++ b/crypto/src/asn1/cmp/InfoTypeAndValue.cs @@ -50,54 +50,47 @@ namespace Org.BouncyCastle.Asn1.Cmp public class InfoTypeAndValue : Asn1Encodable { - private readonly DerObjectIdentifier infoType; - private readonly Asn1Encodable infoValue; + private readonly DerObjectIdentifier m_infoType; + private readonly Asn1Encodable m_infoValue; private InfoTypeAndValue(Asn1Sequence seq) { - infoType = DerObjectIdentifier.GetInstance(seq[0]); + m_infoType = DerObjectIdentifier.GetInstance(seq[0]); if (seq.Count > 1) { - infoValue = (Asn1Encodable)seq[1]; + m_infoValue = seq[1]; } } public static InfoTypeAndValue GetInstance(object obj) { - if (obj is InfoTypeAndValue) - return (InfoTypeAndValue)obj; + if (obj is InfoTypeAndValue infoTypeAndValue) + return infoTypeAndValue; - if (obj is Asn1Sequence) - return new InfoTypeAndValue((Asn1Sequence)obj); + if (obj != null) + return new InfoTypeAndValue(Asn1Sequence.GetInstance(obj)); - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + return null; } - public InfoTypeAndValue( - DerObjectIdentifier infoType) + public InfoTypeAndValue(DerObjectIdentifier infoType) + : this(infoType, null) { - this.infoType = infoType; - this.infoValue = null; } - public InfoTypeAndValue( - DerObjectIdentifier infoType, - Asn1Encodable optionalValue) + public InfoTypeAndValue(DerObjectIdentifier infoType, Asn1Encodable infoValue) { - this.infoType = infoType; - this.infoValue = optionalValue; - } + if (infoType == null) + throw new ArgumentNullException(nameof(infoType)); - public virtual DerObjectIdentifier InfoType - { - get { return infoType; } + m_infoType = infoType; + m_infoValue = infoValue; } - public virtual Asn1Encodable InfoValue - { - get { return infoValue; } - } + public virtual DerObjectIdentifier InfoType => m_infoType; + + public virtual Asn1Encodable InfoValue => m_infoValue; /** * <pre> @@ -110,9 +103,10 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(infoType); - v.AddOptional(infoValue); - return new DerSequence(v); + if (m_infoValue == null) + return new DerSequence(m_infoType); + + return new DerSequence(m_infoType, m_infoValue); } } } diff --git a/crypto/src/asn1/cmp/KeyRecRepContent.cs b/crypto/src/asn1/cmp/KeyRecRepContent.cs index e35c0e351..6c5ef62f2 100644 --- a/crypto/src/asn1/cmp/KeyRecRepContent.cs +++ b/crypto/src/asn1/cmp/KeyRecRepContent.cs @@ -1,20 +1,29 @@ using System; -using Org.BouncyCastle.Utilities; - namespace Org.BouncyCastle.Asn1.Cmp { public class KeyRecRepContent : Asn1Encodable { - private readonly PkiStatusInfo status; - private readonly CmpCertificate newSigCert; - private readonly Asn1Sequence caCerts; - private readonly Asn1Sequence keyPairHist; + public static KeyRecRepContent GetInstance(object obj) + { + if (obj is KeyRecRepContent keyRecRepContent) + return keyRecRepContent; + + if (obj != null) + return new KeyRecRepContent(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private readonly PkiStatusInfo m_status; + private readonly CmpCertificate m_newSigCert; + private readonly Asn1Sequence m_caCerts; + private readonly Asn1Sequence m_keyPairHist; private KeyRecRepContent(Asn1Sequence seq) { - status = PkiStatusInfo.GetInstance(seq[0]); + m_status = PkiStatusInfo.GetInstance(seq[0]); for (int pos = 1; pos < seq.Count; ++pos) { @@ -22,66 +31,39 @@ namespace Org.BouncyCastle.Asn1.Cmp switch (tObj.TagNo) { - case 0: - newSigCert = CmpCertificate.GetInstance(tObj.GetObject()); - break; - case 1: - caCerts = Asn1Sequence.GetInstance(tObj.GetObject()); - break; - case 2: - keyPairHist = Asn1Sequence.GetInstance(tObj.GetObject()); - break; - default: - throw new ArgumentException("unknown tag number: " + tObj.TagNo, "seq"); + case 0: + m_newSigCert = CmpCertificate.GetInstance(tObj.GetObject()); + break; + case 1: + m_caCerts = Asn1Sequence.GetInstance(tObj.GetObject()); + break; + case 2: + m_keyPairHist = Asn1Sequence.GetInstance(tObj.GetObject()); + break; + default: + throw new ArgumentException("unknown tag number: " + tObj.TagNo, "seq"); } } } - public static KeyRecRepContent GetInstance(object obj) - { - if (obj is KeyRecRepContent) - return (KeyRecRepContent)obj; + public virtual PkiStatusInfo Status => m_status; - if (obj is Asn1Sequence) - return new KeyRecRepContent((Asn1Sequence)obj); - - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); - } - - public virtual PkiStatusInfo Status - { - get { return status; } - } - - public virtual CmpCertificate NewSigCert - { - get { return newSigCert; } - } + public virtual CmpCertificate NewSigCert => m_newSigCert; public virtual CmpCertificate[] GetCACerts() { - if (caCerts == null) + if (m_caCerts == null) return null; - CmpCertificate[] results = new CmpCertificate[caCerts.Count]; - for (int i = 0; i != results.Length; ++i) - { - results[i] = CmpCertificate.GetInstance(caCerts[i]); - } - return results; + return m_caCerts.MapElements(CmpCertificate.GetInstance); } public virtual CertifiedKeyPair[] GetKeyPairHist() { - if (keyPairHist == null) + if (m_keyPairHist == null) return null; - CertifiedKeyPair[] results = new CertifiedKeyPair[keyPairHist.Count]; - for (int i = 0; i != results.Length; ++i) - { - results[i] = CertifiedKeyPair.GetInstance(keyPairHist[i]); - } - return results; + return m_keyPairHist.MapElements(CertifiedKeyPair.GetInstance); } /** @@ -99,10 +81,10 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(status); - v.AddOptionalTagged(true, 0, newSigCert); - v.AddOptionalTagged(true, 1, caCerts); - v.AddOptionalTagged(true, 2, keyPairHist); + Asn1EncodableVector v = new Asn1EncodableVector(m_status); + v.AddOptionalTagged(true, 0, m_newSigCert); + v.AddOptionalTagged(true, 1, m_caCerts); + v.AddOptionalTagged(true, 2, m_keyPairHist); return new DerSequence(v); } } diff --git a/crypto/src/asn1/cmp/NestedMessageContent.cs b/crypto/src/asn1/cmp/NestedMessageContent.cs new file mode 100644 index 000000000..0cb2c080b --- /dev/null +++ b/crypto/src/asn1/cmp/NestedMessageContent.cs @@ -0,0 +1,35 @@ +namespace Org.BouncyCastle.Asn1.Cmp +{ + /** + * NestedMessageContent ::= PKIMessages + */ + public class NestedMessageContent + : PkiMessages + { + public static new NestedMessageContent GetInstance(object obj) + { + if (obj is NestedMessageContent nestedMessageContent) + return nestedMessageContent; + + if (obj != null) + return new NestedMessageContent(Asn1Sequence.GetInstance(obj)); + + return null; + } + + public NestedMessageContent(PkiMessage msg) + : base(msg) + { + } + + public NestedMessageContent(PkiMessage[] msgs) + : base(msgs) + { + } + + public NestedMessageContent(Asn1Sequence seq) + : base(seq) + { + } + } +} diff --git a/crypto/src/asn1/cmp/OobCert.cs b/crypto/src/asn1/cmp/OobCert.cs new file mode 100644 index 000000000..82d5afe55 --- /dev/null +++ b/crypto/src/asn1/cmp/OobCert.cs @@ -0,0 +1,68 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + /** + * OOBCert ::= CMPCertificate + */ + public class OobCert + : CmpCertificate + { + public static new OobCert GetInstance(object obj) + { + if (obj == null) + return null; + + if (obj is OobCert oobCert) + return oobCert; + + if (obj is CmpCertificate cmpCertificate) + return GetInstance(cmpCertificate.GetEncoded()); + + if (obj is byte[] bs) + { + try + { + obj = Asn1Object.FromByteArray(bs); + } + catch (IOException) + { + throw new ArgumentException("Invalid encoding in OobCert"); + } + } + + if (obj is Asn1Sequence seq) + return new OobCert(X509CertificateStructure.GetInstance(obj)); + + if (obj is Asn1TaggedObject taggedObject) + return new OobCert(taggedObject.TagNo, taggedObject.GetObject()); + + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), nameof(obj)); + } + + public static new OobCert GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + if (taggedObject == null) + return null; + + if (!declaredExplicit) + throw new ArgumentException("tag must be explicit"); + + return GetInstance(taggedObject.GetObject()); + } + + public OobCert(int type, Asn1Encodable otherCert) + : base(type, otherCert) + { + } + + public OobCert(X509CertificateStructure x509v3PKCert) + : base(x509v3PKCert) + { + } + } +} diff --git a/crypto/src/asn1/cmp/OobCertHash.cs b/crypto/src/asn1/cmp/OobCertHash.cs index 434939c0e..a18ff300d 100644 --- a/crypto/src/asn1/cmp/OobCertHash.cs +++ b/crypto/src/asn1/cmp/OobCertHash.cs @@ -6,18 +6,40 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1.Cmp { - public class OobCertHash + /** + * <pre> + * OOBCertHash ::= SEQUENCE { + * hashAlg [0] AlgorithmIdentifier OPTIONAL, + * certId [1] CertId OPTIONAL, + * hashVal BIT STRING + * -- hashVal is calculated over the DER encoding of the + * -- self-signed certificate with the identifier certID. + * } + * </pre> + */ + public class OobCertHash : Asn1Encodable { - private readonly AlgorithmIdentifier hashAlg; - private readonly CertId certId; - private readonly DerBitString hashVal; + public static OobCertHash GetInstance(object obj) + { + if (obj is OobCertHash oobCertHash) + return oobCertHash; + + if (obj != null) + return new OobCertHash(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private readonly AlgorithmIdentifier m_hashAlg; + private readonly CertId m_certId; + private readonly DerBitString m_hashVal; private OobCertHash(Asn1Sequence seq) { int index = seq.Count - 1; - hashVal = DerBitString.GetInstance(seq[index--]); + m_hashVal = DerBitString.GetInstance(seq[index--]); for (int i = index; i >= 0; i--) { @@ -25,36 +47,21 @@ namespace Org.BouncyCastle.Asn1.Cmp if (tObj.TagNo == 0) { - hashAlg = AlgorithmIdentifier.GetInstance(tObj, true); + m_hashAlg = AlgorithmIdentifier.GetInstance(tObj, true); } else { - certId = CertId.GetInstance(tObj, true); + m_certId = CertId.GetInstance(tObj, true); } } } - public static OobCertHash GetInstance(object obj) - { - if (obj is OobCertHash) - return (OobCertHash)obj; + public virtual CertId CertID => m_certId; - if (obj is Asn1Sequence) - return new OobCertHash((Asn1Sequence)obj); + public virtual AlgorithmIdentifier HashAlg => m_hashAlg; + + public virtual DerBitString HashVal => m_hashVal; - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); - } - - public virtual AlgorithmIdentifier HashAlg - { - get { return hashAlg; } - } - - public virtual CertId CertID - { - get { return certId; } - } - /** * <pre> * OobCertHash ::= SEQUENCE { @@ -70,9 +77,9 @@ namespace Org.BouncyCastle.Asn1.Cmp public override Asn1Object ToAsn1Object() { Asn1EncodableVector v = new Asn1EncodableVector(); - v.AddOptionalTagged(true, 0, hashAlg); - v.AddOptionalTagged(true, 1, certId); - v.Add(hashVal); + v.AddOptionalTagged(true, 0, m_hashAlg); + v.AddOptionalTagged(true, 1, m_certId); + v.Add(m_hashVal); return new DerSequence(v); } } diff --git a/crypto/src/asn1/cmp/PKIBody.cs b/crypto/src/asn1/cmp/PKIBody.cs index f17eed64d..68f63ab0b 100644 --- a/crypto/src/asn1/cmp/PKIBody.cs +++ b/crypto/src/asn1/cmp/PKIBody.cs @@ -6,6 +6,37 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1.Cmp { + /** + * PKIBody ::= CHOICE { -- message-specific body elements + * ir [0] CertReqMessages, --Initialization Request + * ip [1] CertRepMessage, --Initialization Response + * cr [2] CertReqMessages, --Certification Request + * cp [3] CertRepMessage, --Certification Response + * p10cr [4] CertificationRequest, --imported from [PKCS10] + * popdecc [5] POPODecKeyChallContent, --pop Challenge + * popdecr [6] POPODecKeyRespContent, --pop Response + * kur [7] CertReqMessages, --Key Update Request + * kup [8] CertRepMessage, --Key Update Response + * krr [9] CertReqMessages, --Key Recovery Request + * krp [10] KeyRecRepContent, --Key Recovery Response + * rr [11] RevReqContent, --Revocation Request + * rp [12] RevRepContent, --Revocation Response + * ccr [13] CertReqMessages, --Cross-Cert. Request + * ccp [14] CertRepMessage, --Cross-Cert. Response + * ckuann [15] CAKeyUpdAnnContent, --CA Key Update Ann. + * cann [16] CertAnnContent, --Certificate Ann. + * rann [17] RevAnnContent, --Revocation Ann. + * crlann [18] CRLAnnContent, --CRL Announcement + * pkiconf [19] PKIConfirmContent, --Confirmation + * nested [20] NestedMessageContent, --Nested Message + * genm [21] GenMsgContent, --General Message + * genp [22] GenRepContent, --General Response + * error [23] ErrorMsgContent, --Error Message + * certConf [24] CertConfirmContent, --Certificate confirm + * pollReq [25] PollReqContent, --Polling request + * pollRep [26] PollRepContent --Polling response + * } + */ public class PkiBody : Asn1Encodable, IAsn1Choice { @@ -37,24 +68,27 @@ namespace Org.BouncyCastle.Asn1.Cmp public const int TYPE_POLL_REQ = 25; public const int TYPE_POLL_REP = 26; - private int tagNo; - private Asn1Encodable body; - public static PkiBody GetInstance(object obj) { - if (obj is PkiBody) - return (PkiBody)obj; + if (obj == null) + return null; + + if (obj is PkiBody pkiBody) + return pkiBody; - if (obj is Asn1TaggedObject) - return new PkiBody((Asn1TaggedObject)obj); + if (obj is Asn1TaggedObject taggedObject) + return new PkiBody(taggedObject); - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), nameof(obj)); } - private PkiBody(Asn1TaggedObject tagged) + private readonly int m_tagNo; + private readonly Asn1Encodable m_body; + + private PkiBody(Asn1TaggedObject taggedObject) { - tagNo = tagged.TagNo; - body = GetBodyForType(tagNo, tagged.GetObject()); + m_tagNo = taggedObject.TagNo; + m_body = GetBodyForType(m_tagNo, taggedObject.GetObject()); } /** @@ -62,88 +96,78 @@ namespace Org.BouncyCastle.Asn1.Cmp * @param type one of the TYPE_* constants * @param content message content */ - public PkiBody( - int type, - Asn1Encodable content) + public PkiBody(int type, Asn1Encodable content) { - tagNo = type; - body = GetBodyForType(type, content); + m_tagNo = type; + m_body = GetBodyForType(type, content); } - private static Asn1Encodable GetBodyForType( - int type, - Asn1Encodable o) + private static Asn1Encodable GetBodyForType(int type, Asn1Encodable o) { switch (type) { - case TYPE_INIT_REQ: - return CertReqMessages.GetInstance(o); - case TYPE_INIT_REP: - return CertRepMessage.GetInstance(o); - case TYPE_CERT_REQ: - return CertReqMessages.GetInstance(o); - case TYPE_CERT_REP: - return CertRepMessage.GetInstance(o); - case TYPE_P10_CERT_REQ: - return CertificationRequest.GetInstance(o); - case TYPE_POPO_CHALL: - return PopoDecKeyChallContent.GetInstance(o); - case TYPE_POPO_REP: - return PopoDecKeyRespContent.GetInstance(o); - case TYPE_KEY_UPDATE_REQ: - return CertReqMessages.GetInstance(o); - case TYPE_KEY_UPDATE_REP: - return CertRepMessage.GetInstance(o); - case TYPE_KEY_RECOVERY_REQ: - return CertReqMessages.GetInstance(o); - case TYPE_KEY_RECOVERY_REP: - return KeyRecRepContent.GetInstance(o); - case TYPE_REVOCATION_REQ: - return RevReqContent.GetInstance(o); - case TYPE_REVOCATION_REP: - return RevRepContent.GetInstance(o); - case TYPE_CROSS_CERT_REQ: - return CertReqMessages.GetInstance(o); - case TYPE_CROSS_CERT_REP: - return CertRepMessage.GetInstance(o); - case TYPE_CA_KEY_UPDATE_ANN: - return CAKeyUpdAnnContent.GetInstance(o); - case TYPE_CERT_ANN: - return CmpCertificate.GetInstance(o); - case TYPE_REVOCATION_ANN: - return RevAnnContent.GetInstance(o); - case TYPE_CRL_ANN: - return CrlAnnContent.GetInstance(o); - case TYPE_CONFIRM: - return PkiConfirmContent.GetInstance(o); - case TYPE_NESTED: - return PkiMessages.GetInstance(o); - case TYPE_GEN_MSG: - return GenMsgContent.GetInstance(o); - case TYPE_GEN_REP: - return GenRepContent.GetInstance(o); - case TYPE_ERROR: - return ErrorMsgContent.GetInstance(o); - case TYPE_CERT_CONFIRM: - return CertConfirmContent.GetInstance(o); - case TYPE_POLL_REQ: - return PollReqContent.GetInstance(o); - case TYPE_POLL_REP: - return PollRepContent.GetInstance(o); - default: - throw new ArgumentException("unknown tag number: " + type, "type"); + case TYPE_INIT_REQ: + return CertReqMessages.GetInstance(o); + case TYPE_INIT_REP: + return CertRepMessage.GetInstance(o); + case TYPE_CERT_REQ: + return CertReqMessages.GetInstance(o); + case TYPE_CERT_REP: + return CertRepMessage.GetInstance(o); + case TYPE_P10_CERT_REQ: + return CertificationRequest.GetInstance(o); + case TYPE_POPO_CHALL: + return PopoDecKeyChallContent.GetInstance(o); + case TYPE_POPO_REP: + return PopoDecKeyRespContent.GetInstance(o); + case TYPE_KEY_UPDATE_REQ: + return CertReqMessages.GetInstance(o); + case TYPE_KEY_UPDATE_REP: + return CertRepMessage.GetInstance(o); + case TYPE_KEY_RECOVERY_REQ: + return CertReqMessages.GetInstance(o); + case TYPE_KEY_RECOVERY_REP: + return KeyRecRepContent.GetInstance(o); + case TYPE_REVOCATION_REQ: + return RevReqContent.GetInstance(o); + case TYPE_REVOCATION_REP: + return RevRepContent.GetInstance(o); + case TYPE_CROSS_CERT_REQ: + return CertReqMessages.GetInstance(o); + case TYPE_CROSS_CERT_REP: + return CertRepMessage.GetInstance(o); + case TYPE_CA_KEY_UPDATE_ANN: + return CAKeyUpdAnnContent.GetInstance(o); + case TYPE_CERT_ANN: + return CmpCertificate.GetInstance(o); + case TYPE_REVOCATION_ANN: + return RevAnnContent.GetInstance(o); + case TYPE_CRL_ANN: + return CrlAnnContent.GetInstance(o); + case TYPE_CONFIRM: + return PkiConfirmContent.GetInstance(o); + case TYPE_NESTED: + return PkiMessages.GetInstance(o); + case TYPE_GEN_MSG: + return GenMsgContent.GetInstance(o); + case TYPE_GEN_REP: + return GenRepContent.GetInstance(o); + case TYPE_ERROR: + return ErrorMsgContent.GetInstance(o); + case TYPE_CERT_CONFIRM: + return CertConfirmContent.GetInstance(o); + case TYPE_POLL_REQ: + return PollReqContent.GetInstance(o); + case TYPE_POLL_REP: + return PollRepContent.GetInstance(o); + default: + throw new ArgumentException("unknown tag number: " + type, nameof(type)); } } - public virtual int Type - { - get { return tagNo; } - } + public virtual Asn1Encodable Content => m_body; - public virtual Asn1Encodable Content - { - get { return body; } - } + public virtual int Type => m_tagNo; /** * <pre> @@ -181,7 +205,7 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - return new DerTaggedObject(true, tagNo, body); + return new DerTaggedObject(true, m_tagNo, m_body); } } } diff --git a/crypto/src/asn1/cmp/PKIConfirmContent.cs b/crypto/src/asn1/cmp/PKIConfirmContent.cs index d154427a4..ecebb22a8 100644 --- a/crypto/src/asn1/cmp/PKIConfirmContent.cs +++ b/crypto/src/asn1/cmp/PKIConfirmContent.cs @@ -4,24 +4,38 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1.Cmp { - public class PkiConfirmContent + /** + * PKIConfirmContent ::= NULL + */ + public class PkiConfirmContent : Asn1Encodable { public static PkiConfirmContent GetInstance(object obj) { - if (obj is PkiConfirmContent) - return (PkiConfirmContent)obj; + if (obj == null) + return null; - if (obj is Asn1Null) - return new PkiConfirmContent(); + if (obj is PkiConfirmContent pkiConfirmContent) + return pkiConfirmContent; - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); - } + if (obj is Asn1Null asn1Null) + return new PkiConfirmContent(asn1Null); - public PkiConfirmContent() - { + throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), nameof(obj)); } + private readonly Asn1Null m_val; + + public PkiConfirmContent() + : this(DerNull.Instance) + { + } + + private PkiConfirmContent(Asn1Null val) + { + m_val = val; + } + /** * <pre> * PkiConfirmContent ::= NULL @@ -30,7 +44,7 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - return DerNull.Instance; + return m_val; } } } diff --git a/crypto/src/asn1/cmp/PKIFailureInfo.cs b/crypto/src/asn1/cmp/PKIFailureInfo.cs index 75a3ff0d7..fd37665b9 100644 --- a/crypto/src/asn1/cmp/PKIFailureInfo.cs +++ b/crypto/src/asn1/cmp/PKIFailureInfo.cs @@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Asn1.Cmp * certRevoked (10), * certConfirmed (11), * wrongIntegrity (12), - * badRecipientNonce (13), + * badRecipientNonce (13), * timeNotAvailable (14), * -- the TSA's time source is not available * unacceptedPolicy (15), @@ -37,13 +37,13 @@ namespace Org.BouncyCastle.Asn1.Cmp * transactionIdInUse (21), * unsupportedVersion (22), * notAuthorized (23), - * systemUnavail (24), + * systemUnavail (24), * systemFailure (25), * -- the request cannot be handled due to system failure - * duplicateCertReq (26) + * duplicateCertReq (26) * </pre> */ - public class PkiFailureInfo + public class PkiFailureInfo : DerBitString { public const int BadAlg = (1 << 7); // unrecognized or unsupported Algorithm Identifier diff --git a/crypto/src/asn1/cmp/PKIFreeText.cs b/crypto/src/asn1/cmp/PKIFreeText.cs index 006930320..f3a4b8a81 100644 --- a/crypto/src/asn1/cmp/PKIFreeText.cs +++ b/crypto/src/asn1/cmp/PKIFreeText.cs @@ -1,61 +1,66 @@ using System; -using Org.BouncyCastle.Utilities; - namespace Org.BouncyCastle.Asn1.Cmp { public class PkiFreeText : Asn1Encodable { - internal Asn1Sequence strings; - - public static PkiFreeText GetInstance( - Asn1TaggedObject obj, - bool isExplicit) + public static PkiFreeText GetInstance(object obj) { - return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit)); + if (obj is PkiFreeText pkiFreeText) + return pkiFreeText; + + if (obj != null) + return new PkiFreeText(Asn1Sequence.GetInstance(obj)); + + return null; } - public static PkiFreeText GetInstance( - object obj) + public static PkiFreeText GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return GetInstance(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } + + internal Asn1Sequence m_strings; + + internal PkiFreeText(Asn1Sequence seq) { - if (obj is PkiFreeText) - { - return (PkiFreeText)obj; - } - else if (obj is Asn1Sequence) + foreach (var element in seq) { - return new PkiFreeText((Asn1Sequence)obj); + if (!(element is DerUtf8String)) + throw new ArgumentException("attempt to insert non UTF8 STRING into PkiFreeText"); } - throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); + m_strings = seq; } - public PkiFreeText( - Asn1Sequence seq) + public PkiFreeText(DerUtf8String p) { - foreach (object o in seq) - { - if (!(o is DerUtf8String)) - { - throw new ArgumentException("attempt to insert non UTF8 STRING into PkiFreeText"); - } - } + m_strings = new DerSequence(p); + } - this.strings = seq; + public PkiFreeText(string p) + : this(new DerUtf8String(p)) + { } - public PkiFreeText( - DerUtf8String p) + public PkiFreeText(DerUtf8String[] strs) { - strings = new DerSequence(p); + m_strings = new DerSequence(strs); } - public int Count + public PkiFreeText(string[] strs) { - get { return strings.Count; } + Asn1EncodableVector v = new Asn1EncodableVector(strs.Length); + for (int i = 0; i < strs.Length; i++) + { + v.Add(new DerUtf8String(strs[i])); + } + m_strings = new DerSequence(v); } + public virtual int Count => m_strings.Count; + /** * Return the UTF8STRING at index. * @@ -64,7 +69,7 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public DerUtf8String this[int index] { - get { return (DerUtf8String) strings[index]; } + get { return (DerUtf8String)m_strings[index]; } } /** @@ -74,7 +79,7 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - return strings; + return m_strings; } } } diff --git a/crypto/src/asn1/cmp/PKIHeader.cs b/crypto/src/asn1/cmp/PKIHeader.cs index 7b6296279..7ed914e6a 100644 --- a/crypto/src/asn1/cmp/PKIHeader.cs +++ b/crypto/src/asn1/cmp/PKIHeader.cs @@ -19,7 +19,7 @@ namespace Org.BouncyCastle.Asn1.Cmp private readonly DerInteger pvno; private readonly GeneralName sender; private readonly GeneralName recipient; - private readonly DerGeneralizedTime messageTime; + private readonly Asn1GeneralizedTime messageTime; private readonly AlgorithmIdentifier protectionAlg; private readonly Asn1OctetString senderKID; // KeyIdentifier private readonly Asn1OctetString recipKID; // KeyIdentifier @@ -41,35 +41,35 @@ namespace Org.BouncyCastle.Asn1.Cmp switch (tObj.TagNo) { - case 0: - messageTime = DerGeneralizedTime.GetInstance(tObj, true); - break; - case 1: - protectionAlg = AlgorithmIdentifier.GetInstance(tObj, true); - break; - case 2: - senderKID = Asn1OctetString.GetInstance(tObj, true); - break; - case 3: - recipKID = Asn1OctetString.GetInstance(tObj, true); - break; - case 4: - transactionID = Asn1OctetString.GetInstance(tObj, true); - break; - case 5: - senderNonce = Asn1OctetString.GetInstance(tObj, true); - break; - case 6: - recipNonce = Asn1OctetString.GetInstance(tObj, true); - break; - case 7: - freeText = PkiFreeText.GetInstance(tObj, true); - break; - case 8: - generalInfo = Asn1Sequence.GetInstance(tObj, true); - break; - default: - throw new ArgumentException("unknown tag number: " + tObj.TagNo, "seq"); + case 0: + messageTime = Asn1GeneralizedTime.GetInstance(tObj, true); + break; + case 1: + protectionAlg = AlgorithmIdentifier.GetInstance(tObj, true); + break; + case 2: + senderKID = Asn1OctetString.GetInstance(tObj, true); + break; + case 3: + recipKID = Asn1OctetString.GetInstance(tObj, true); + break; + case 4: + transactionID = Asn1OctetString.GetInstance(tObj, true); + break; + case 5: + senderNonce = Asn1OctetString.GetInstance(tObj, true); + break; + case 6: + recipNonce = Asn1OctetString.GetInstance(tObj, true); + break; + case 7: + freeText = PkiFreeText.GetInstance(tObj, true); + break; + case 8: + generalInfo = Asn1Sequence.GetInstance(tObj, true); + break; + default: + throw new ArgumentException("unknown tag number: " + tObj.TagNo, nameof(seq)); } } } @@ -118,7 +118,7 @@ namespace Org.BouncyCastle.Asn1.Cmp get { return recipient; } } - public virtual DerGeneralizedTime MessageTime + public virtual Asn1GeneralizedTime MessageTime { get { return messageTime; } } diff --git a/crypto/src/asn1/cmp/PKIHeaderBuilder.cs b/crypto/src/asn1/cmp/PKIHeaderBuilder.cs index d771dda4c..cbefc73b8 100644 --- a/crypto/src/asn1/cmp/PKIHeaderBuilder.cs +++ b/crypto/src/asn1/cmp/PKIHeaderBuilder.cs @@ -9,7 +9,7 @@ namespace Org.BouncyCastle.Asn1.Cmp private DerInteger pvno; private GeneralName sender; private GeneralName recipient; - private DerGeneralizedTime messageTime; + private Asn1GeneralizedTime messageTime; private AlgorithmIdentifier protectionAlg; private Asn1OctetString senderKID; // KeyIdentifier private Asn1OctetString recipKID; // KeyIdentifier @@ -37,7 +37,7 @@ namespace Org.BouncyCastle.Asn1.Cmp this.recipient = recipient; } - public virtual PkiHeaderBuilder SetMessageTime(DerGeneralizedTime time) + public virtual PkiHeaderBuilder SetMessageTime(Asn1GeneralizedTime time) { messageTime = time; return this; diff --git a/crypto/src/asn1/cmp/PKIMessages.cs b/crypto/src/asn1/cmp/PKIMessages.cs index eb01e544a..0008f476a 100644 --- a/crypto/src/asn1/cmp/PKIMessages.cs +++ b/crypto/src/asn1/cmp/PKIMessages.cs @@ -9,7 +9,7 @@ namespace Org.BouncyCastle.Asn1.Cmp { private Asn1Sequence content; - private PkiMessages(Asn1Sequence seq) + internal PkiMessages(Asn1Sequence seq) { content = seq; } diff --git a/crypto/src/asn1/cmp/PbmParameter.cs b/crypto/src/asn1/cmp/PbmParameter.cs index 206b89ba1..f4b702ed5 100644 --- a/crypto/src/asn1/cmp/PbmParameter.cs +++ b/crypto/src/asn1/cmp/PbmParameter.cs @@ -1,77 +1,74 @@ using System; using Org.BouncyCastle.Asn1.X509; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1.Cmp { + /** + * PBMParameter ::= SEQUENCE { + * salt OCTET STRING, + * -- note: implementations MAY wish to limit acceptable sizes + * -- of this string to values appropriate for their environment + * -- in order to reduce the risk of denial-of-service attacks + * owf AlgorithmIdentifier, + * -- AlgId for a One-Way Function (SHA-1 recommended) + * iterationCount INTEGER, + * -- number of times the OWF is applied + * -- note: implementations MAY wish to limit acceptable sizes + * -- of this integer to values appropriate for their environment + * -- in order to reduce the risk of denial-of-service attacks + * mac AlgorithmIdentifier + * -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11], + * } -- or HMAC [RFC2104, RFC2202]) + */ public class PbmParameter : Asn1Encodable { - private Asn1OctetString salt; - private AlgorithmIdentifier owf; - private DerInteger iterationCount; - private AlgorithmIdentifier mac; - - private PbmParameter(Asn1Sequence seq) - { - salt = Asn1OctetString.GetInstance(seq[0]); - owf = AlgorithmIdentifier.GetInstance(seq[1]); - iterationCount = DerInteger.GetInstance(seq[2]); - mac = AlgorithmIdentifier.GetInstance(seq[3]); - } - public static PbmParameter GetInstance(object obj) { - if (obj is PbmParameter) - return (PbmParameter)obj; + if (obj is PbmParameter pbmParameter) + return pbmParameter; - if (obj is Asn1Sequence) - return new PbmParameter((Asn1Sequence)obj); + if (obj != null) + return new PbmParameter(Asn1Sequence.GetInstance(obj)); - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + return null; } - public PbmParameter( - byte[] salt, - AlgorithmIdentifier owf, - int iterationCount, - AlgorithmIdentifier mac) - : this(new DerOctetString(salt), owf, new DerInteger(iterationCount), mac) - { - } + private readonly Asn1OctetString m_salt; + private readonly AlgorithmIdentifier m_owf; + private readonly DerInteger m_iterationCount; + private readonly AlgorithmIdentifier m_mac; - public PbmParameter( - Asn1OctetString salt, - AlgorithmIdentifier owf, - DerInteger iterationCount, - AlgorithmIdentifier mac) + private PbmParameter(Asn1Sequence seq) { - this.salt = salt; - this.owf = owf; - this.iterationCount = iterationCount; - this.mac = mac; + m_salt = Asn1OctetString.GetInstance(seq[0]); + m_owf = AlgorithmIdentifier.GetInstance(seq[1]); + m_iterationCount = DerInteger.GetInstance(seq[2]); + m_mac = AlgorithmIdentifier.GetInstance(seq[3]); } - public virtual Asn1OctetString Salt + public PbmParameter(byte[] salt, AlgorithmIdentifier owf, int iterationCount, AlgorithmIdentifier mac) + : this(new DerOctetString(salt), owf, new DerInteger(iterationCount), mac) { - get { return salt; } } - public virtual AlgorithmIdentifier Owf + public PbmParameter(Asn1OctetString salt, AlgorithmIdentifier owf, DerInteger iterationCount, + AlgorithmIdentifier mac) { - get { return owf; } + m_salt = salt; + m_owf = owf; + m_iterationCount = iterationCount; + m_mac = mac; } - public virtual DerInteger IterationCount - { - get { return iterationCount; } - } + public virtual DerInteger IterationCount => m_iterationCount; - public virtual AlgorithmIdentifier Mac - { - get { return mac; } - } + public virtual AlgorithmIdentifier Mac => m_mac; + + public virtual AlgorithmIdentifier Owf => m_owf; + + public virtual Asn1OctetString Salt => m_salt; /** * <pre> @@ -95,7 +92,7 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - return new DerSequence(salt, owf, iterationCount, mac); + return new DerSequence(m_salt, m_owf, m_iterationCount, m_mac); } } } diff --git a/crypto/src/asn1/cmp/PollRepContent.cs b/crypto/src/asn1/cmp/PollRepContent.cs index ff75d7d6d..15f153a5d 100644 --- a/crypto/src/asn1/cmp/PollRepContent.cs +++ b/crypto/src/asn1/cmp/PollRepContent.cs @@ -1,71 +1,69 @@ -using System; - -using Org.BouncyCastle.Utilities; - namespace Org.BouncyCastle.Asn1.Cmp { - public class PollRepContent + /** + * PollRepContent ::= SEQUENCE OF SEQUENCE { + * certReqId INTEGER, + * checkAfter INTEGER, -- time in seconds + * reason PKIFreeText OPTIONAL } + */ + public class PollRepContent : Asn1Encodable { - private readonly DerInteger certReqId; - private readonly DerInteger checkAfter; - private readonly PkiFreeText reason; + public static PollRepContent GetInstance(object obj) + { + if (obj is PollRepContent pollRepContent) + return pollRepContent; + + if (obj != null) + return new PollRepContent(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private readonly DerInteger[] m_certReqID; + private readonly DerInteger[] m_checkAfter; + private readonly PkiFreeText[] m_reason; private PollRepContent(Asn1Sequence seq) { - certReqId = DerInteger.GetInstance(seq[0]); - checkAfter = DerInteger.GetInstance(seq[1]); + int count = seq.Count; + m_certReqID = new DerInteger[count]; + m_checkAfter = new DerInteger[count]; + m_reason = new PkiFreeText[count]; - if (seq.Count > 2) + for (int i = 0; i != count; i++) { - reason = PkiFreeText.GetInstance(seq[2]); - } - } - - public static PollRepContent GetInstance(object obj) - { - if (obj is PollRepContent) - return (PollRepContent)obj; + Asn1Sequence s = Asn1Sequence.GetInstance(seq[i]); - if (obj is Asn1Sequence) - return new PollRepContent((Asn1Sequence)obj); + m_certReqID[i] = DerInteger.GetInstance(s[0]); + m_checkAfter[i] = DerInteger.GetInstance(s[1]); - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + if (s.Count > 2) + { + m_reason[i] = PkiFreeText.GetInstance(s[2]); + } + } } - public PollRepContent( - DerInteger certReqId, - DerInteger checkAfter) + public PollRepContent(DerInteger certReqID, DerInteger checkAfter) + : this(certReqID, checkAfter, null) { - this.certReqId = certReqId; - this.checkAfter = checkAfter; - this.reason = null; } - public PollRepContent( - DerInteger certReqId, - DerInteger checkAfter, - PkiFreeText reason) + public PollRepContent(DerInteger certReqID, DerInteger checkAfter, PkiFreeText reason) { - this.certReqId = certReqId; - this.checkAfter = checkAfter; - this.reason = reason; - } + m_certReqID = new DerInteger[1]{ certReqID }; + m_checkAfter = new DerInteger[1]{ checkAfter }; + m_reason = new PkiFreeText[1]{ reason }; + } - public virtual DerInteger CertReqID - { - get { return certReqId; } - } + public virtual int Count => m_certReqID.Length; - public virtual DerInteger CheckAfter - { - get { return checkAfter; } - } + public virtual DerInteger GetCertReqID(int index) => m_certReqID[index]; - public virtual PkiFreeText Reason - { - get { return reason; } - } + public virtual DerInteger GetCheckAfter(int index) => m_checkAfter[index]; + + public virtual PkiFreeText GetReason(int index) => m_reason[index]; /** * <pre> @@ -79,9 +77,20 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(certReqId, checkAfter); - v.AddOptional(reason); - return new DerSequence(v); + Asn1EncodableVector outer = new Asn1EncodableVector(m_certReqID.Length); + + for (int i = 0; i != m_certReqID.Length; i++) + { + Asn1EncodableVector v = new Asn1EncodableVector(3); + + v.Add(m_certReqID[i]); + v.Add(m_checkAfter[i]); + v.AddOptional(m_reason[i]); + + outer.Add(new DerSequence(v)); + } + + return new DerSequence(outer); } } } diff --git a/crypto/src/asn1/cmp/PollReqContent.cs b/crypto/src/asn1/cmp/PollReqContent.cs index dd9b0c352..80a39348a 100644 --- a/crypto/src/asn1/cmp/PollReqContent.cs +++ b/crypto/src/asn1/cmp/PollReqContent.cs @@ -1,51 +1,91 @@ -using System; - -using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Math; namespace Org.BouncyCastle.Asn1.Cmp { public class PollReqContent : Asn1Encodable { - private readonly Asn1Sequence content; + public static PollReqContent GetInstance(object obj) + { + if (obj is PollReqContent pollReqContent) + return pollReqContent; + + if (obj != null) + return new PollReqContent(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private readonly Asn1Sequence m_content; private PollReqContent(Asn1Sequence seq) { - content = seq; + m_content = seq; } - public static PollReqContent GetInstance(object obj) + /** + * Create a pollReqContent for a single certReqId. + * + * @param certReqId the certificate request ID. + */ + public PollReqContent(DerInteger certReqId) + : this(new DerSequence(new DerSequence(certReqId))) { - if (obj is PollReqContent) - return (PollReqContent)obj; + } - if (obj is Asn1Sequence) - return new PollReqContent((Asn1Sequence)obj); + /** + * Create a pollReqContent for a multiple certReqIds. + * + * @param certReqIds the certificate request IDs. + */ + public PollReqContent(DerInteger[] certReqIds) + : this(new DerSequence(IntsToSequence(certReqIds))) + { + } - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + /** + * Create a pollReqContent for a single certReqId. + * + * @param certReqId the certificate request ID. + */ + public PollReqContent(BigInteger certReqId) + : this(new DerInteger(certReqId)) + { } - public virtual DerInteger[][] GetCertReqIDs() + /** + * Create a pollReqContent for a multiple certReqIds. + * + * @param certReqIds the certificate request IDs. + */ + public PollReqContent(BigInteger[] certReqIds) + : this(IntsToAsn1(certReqIds)) { - DerInteger[][] result = new DerInteger[content.Count][]; - for (int i = 0; i != result.Length; ++i) - { - result[i] = SequenceToDerIntegerArray((Asn1Sequence)content[i]); - } - return result; } - private static DerInteger[] SequenceToDerIntegerArray(Asn1Sequence seq) + public virtual DerInteger[][] GetCertReqIDs() { - DerInteger[] result = new DerInteger[seq.Count]; + DerInteger[][] result = new DerInteger[m_content.Count][]; for (int i = 0; i != result.Length; ++i) { - result[i] = DerInteger.GetInstance(seq[i]); + result[i] = SequenceToDerIntegerArray((Asn1Sequence)m_content[i]); } return result; } - /** + public virtual BigInteger[] GetCertReqIDValues() + { + BigInteger[] result = new BigInteger[m_content.Count]; + + for (int i = 0; i != result.Length; i++) + { + result[i] = DerInteger.GetInstance(Asn1Sequence.GetInstance(m_content[i])[0]).Value; + } + + return result; + } + + /** * <pre> * PollReqContent ::= SEQUENCE OF SEQUENCE { * certReqId INTEGER @@ -53,9 +93,38 @@ namespace Org.BouncyCastle.Asn1.Cmp * </pre> * @return a basic ASN.1 object representation. */ - public override Asn1Object ToAsn1Object() + public override Asn1Object ToAsn1Object() + { + return m_content; + } + + private static DerInteger[] SequenceToDerIntegerArray(Asn1Sequence seq) + { + return seq.MapElements(DerInteger.GetInstance); + } + + private static DerSequence[] IntsToSequence(DerInteger[] ids) { - return content; + DerSequence[] result = new DerSequence[ids.Length]; + + for (int i = 0; i != result.Length; i++) + { + result[i] = new DerSequence(ids[i]); + } + + return result; + } + + private static DerInteger[] IntsToAsn1(BigInteger[] ids) + { + DerInteger[] result = new DerInteger[ids.Length]; + + for (int i = 0; i != result.Length; i++) + { + result[i] = new DerInteger(ids[i]); + } + + return result; } } } diff --git a/crypto/src/asn1/cmp/PopoDecKeyChallContent.cs b/crypto/src/asn1/cmp/PopoDecKeyChallContent.cs index 03a13a5d5..0bd1597c8 100644 --- a/crypto/src/asn1/cmp/PopoDecKeyChallContent.cs +++ b/crypto/src/asn1/cmp/PopoDecKeyChallContent.cs @@ -1,38 +1,31 @@ using System; -using Org.BouncyCastle.Utilities; - namespace Org.BouncyCastle.Asn1.Cmp { public class PopoDecKeyChallContent : Asn1Encodable { - private readonly Asn1Sequence content; + public static PopoDecKeyChallContent GetInstance(object obj) + { + if (obj is PopoDecKeyChallContent popoDecKeyChallContent) + return popoDecKeyChallContent; - private PopoDecKeyChallContent(Asn1Sequence seq) - { - content = seq; - } + if (obj != null) + return new PopoDecKeyChallContent(Asn1Sequence.GetInstance(obj)); - public static PopoDecKeyChallContent GetInstance(object obj) - { - if (obj is PopoDecKeyChallContent) - return (PopoDecKeyChallContent)obj; + return null; + } - if (obj is Asn1Sequence) - return new PopoDecKeyChallContent((Asn1Sequence)obj); + private readonly Asn1Sequence m_content; - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + private PopoDecKeyChallContent(Asn1Sequence seq) + { + m_content = seq; } public virtual Challenge[] ToChallengeArray() { - Challenge[] result = new Challenge[content.Count]; - for (int i = 0; i != result.Length; ++i) - { - result[i] = Challenge.GetInstance(content[i]); - } - return result; + return m_content.MapElements(Challenge.GetInstance); } /** @@ -43,7 +36,7 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - return content; + return m_content; } } } diff --git a/crypto/src/asn1/cmp/PopoDecKeyRespContent.cs b/crypto/src/asn1/cmp/PopoDecKeyRespContent.cs index 73f59b7c1..77d720271 100644 --- a/crypto/src/asn1/cmp/PopoDecKeyRespContent.cs +++ b/crypto/src/asn1/cmp/PopoDecKeyRespContent.cs @@ -1,38 +1,29 @@ -using System; - -using Org.BouncyCastle.Utilities; - namespace Org.BouncyCastle.Asn1.Cmp { public class PopoDecKeyRespContent : Asn1Encodable { - private readonly Asn1Sequence content; + public static PopoDecKeyRespContent GetInstance(object obj) + { + if (obj is PopoDecKeyRespContent popoDecKeyRespContent) + return popoDecKeyRespContent; - private PopoDecKeyRespContent(Asn1Sequence seq) - { - content = seq; - } + if (obj != null) + return new PopoDecKeyRespContent(Asn1Sequence.GetInstance(obj)); - public static PopoDecKeyRespContent GetInstance(object obj) - { - if (obj is PopoDecKeyRespContent) - return (PopoDecKeyRespContent)obj; + return null; + } - if (obj is Asn1Sequence) - return new PopoDecKeyRespContent((Asn1Sequence)obj); + private readonly Asn1Sequence m_content; - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + private PopoDecKeyRespContent(Asn1Sequence seq) + { + m_content = seq; } - public virtual DerInteger[] ToDerIntegerArray() + public virtual DerInteger[] ToIntegerArray() { - DerInteger[] result = new DerInteger[content.Count]; - for (int i = 0; i != result.Length; ++i) - { - result[i] = DerInteger.GetInstance(content[i]); - } - return result; + return m_content.MapElements(DerInteger.GetInstance); } /** @@ -43,7 +34,7 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - return content; + return m_content; } } } diff --git a/crypto/src/asn1/cmp/ProtectedPart.cs b/crypto/src/asn1/cmp/ProtectedPart.cs index ed90708f9..fc83ac6c6 100644 --- a/crypto/src/asn1/cmp/ProtectedPart.cs +++ b/crypto/src/asn1/cmp/ProtectedPart.cs @@ -1,47 +1,37 @@ -using System; - -using Org.BouncyCastle.Utilities; - namespace Org.BouncyCastle.Asn1.Cmp { public class ProtectedPart : Asn1Encodable { - private readonly PkiHeader header; - private readonly PkiBody body; - - private ProtectedPart(Asn1Sequence seq) - { - header = PkiHeader.GetInstance(seq[0]); - body = PkiBody.GetInstance(seq[1]); - } + public static ProtectedPart GetInstance(object obj) + { + if (obj is ProtectedPart protectedPart) + return protectedPart; - public static ProtectedPart GetInstance(object obj) - { - if (obj is ProtectedPart) - return (ProtectedPart)obj; + if (obj != null) + return new ProtectedPart(Asn1Sequence.GetInstance(obj)); - if (obj is Asn1Sequence) - return new ProtectedPart((Asn1Sequence)obj); + return null; + } - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); - } + private readonly PkiHeader m_header; + private readonly PkiBody m_body; - public ProtectedPart(PkiHeader header, PkiBody body) + private ProtectedPart(Asn1Sequence seq) { - this.header = header; - this.body = body; + m_header = PkiHeader.GetInstance(seq[0]); + m_body = PkiBody.GetInstance(seq[1]); } - public virtual PkiHeader Header + public ProtectedPart(PkiHeader header, PkiBody body) { - get { return header; } + m_header = header; + m_body = body; } - public virtual PkiBody Body - { - get { return body; } - } + public virtual PkiHeader Header => m_header; + + public virtual PkiBody Body => m_body; /** * <pre> @@ -54,7 +44,7 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - return new DerSequence(header, body); + return new DerSequence(m_header, m_body); } } } diff --git a/crypto/src/asn1/cmp/RevAnnContent.cs b/crypto/src/asn1/cmp/RevAnnContent.cs index d5d42625c..cdd26c39f 100644 --- a/crypto/src/asn1/cmp/RevAnnContent.cs +++ b/crypto/src/asn1/cmp/RevAnnContent.cs @@ -1,68 +1,66 @@ -using System; - using Org.BouncyCastle.Asn1.Crmf; using Org.BouncyCastle.Asn1.X509; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1.Cmp { public class RevAnnContent : Asn1Encodable { - private readonly PkiStatusEncodable status; - private readonly CertId certId; - private readonly DerGeneralizedTime willBeRevokedAt; - private readonly DerGeneralizedTime badSinceDate; - private readonly X509Extensions crlDetails; + public static RevAnnContent GetInstance(object obj) + { + if (obj is RevAnnContent revAnnContent) + return revAnnContent; - private RevAnnContent(Asn1Sequence seq) - { - status = PkiStatusEncodable.GetInstance(seq[0]); - certId = CertId.GetInstance(seq[1]); - willBeRevokedAt = DerGeneralizedTime.GetInstance(seq[2]); - badSinceDate = DerGeneralizedTime.GetInstance(seq[3]); + if (obj != null) + return new RevAnnContent(Asn1Sequence.GetInstance(obj)); - if (seq.Count > 4) - { - crlDetails = X509Extensions.GetInstance(seq[4]); - } - } + return null; + } - public static RevAnnContent GetInstance(object obj) - { - if (obj is RevAnnContent) - return (RevAnnContent)obj; - - if (obj is Asn1Sequence) - return new RevAnnContent((Asn1Sequence)obj); + private readonly PkiStatusEncodable m_status; + private readonly CertId m_certID; + private readonly Asn1GeneralizedTime m_willBeRevokedAt; + private readonly Asn1GeneralizedTime m_badSinceDate; + private readonly X509Extensions m_crlDetails; - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + public RevAnnContent(PkiStatusEncodable status, CertId certID, Asn1GeneralizedTime willBeRevokedAt, + Asn1GeneralizedTime badSinceDate) + : this(status, certID, willBeRevokedAt, badSinceDate, null) + { } - public virtual PkiStatusEncodable Status - { - get { return status; } - } + public RevAnnContent(PkiStatusEncodable status, CertId certID, Asn1GeneralizedTime willBeRevokedAt, + Asn1GeneralizedTime badSinceDate, X509Extensions crlDetails) + { + m_status = status; + m_certID = certID; + m_willBeRevokedAt = willBeRevokedAt; + m_badSinceDate = badSinceDate; + m_crlDetails = crlDetails; + } - public virtual CertId CertID + private RevAnnContent(Asn1Sequence seq) { - get { return certId; } - } + m_status = PkiStatusEncodable.GetInstance(seq[0]); + m_certID = CertId.GetInstance(seq[1]); + m_willBeRevokedAt = Asn1GeneralizedTime.GetInstance(seq[2]); + m_badSinceDate = Asn1GeneralizedTime.GetInstance(seq[3]); - public virtual DerGeneralizedTime WillBeRevokedAt - { - get { return willBeRevokedAt; } + if (seq.Count > 4) + { + m_crlDetails = X509Extensions.GetInstance(seq[4]); + } } - public virtual DerGeneralizedTime BadSinceDate - { - get { return badSinceDate; } - } + public virtual PkiStatusEncodable Status => m_status; - public virtual X509Extensions CrlDetails - { - get { return crlDetails; } - } + public virtual CertId CertID => m_certID; + + public virtual Asn1GeneralizedTime WillBeRevokedAt => m_willBeRevokedAt; + + public virtual Asn1GeneralizedTime BadSinceDate => m_badSinceDate; + + public virtual X509Extensions CrlDetails => m_crlDetails; /** * <pre> @@ -79,8 +77,8 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(status, certId, willBeRevokedAt, badSinceDate); - v.AddOptional(crlDetails); + Asn1EncodableVector v = new Asn1EncodableVector(m_status, m_certID, m_willBeRevokedAt, m_badSinceDate); + v.AddOptional(m_crlDetails); return new DerSequence(v); } } diff --git a/crypto/src/asn1/cmp/RevDetails.cs b/crypto/src/asn1/cmp/RevDetails.cs index 7d2a65ab9..9472d7775 100644 --- a/crypto/src/asn1/cmp/RevDetails.cs +++ b/crypto/src/asn1/cmp/RevDetails.cs @@ -1,56 +1,61 @@ -using System; - using Org.BouncyCastle.Asn1.Crmf; using Org.BouncyCastle.Asn1.X509; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1.Cmp { - public class RevDetails + /** + * <pre> + * RevDetails ::= SEQUENCE { + * certDetails CertTemplate, + * -- allows requester to specify as much as they can about + * -- the cert. for which revocation is requested + * -- (e.g., for cases in which serialNumber is not available) + * crlEntryDetails Extensions OPTIONAL + * -- requested crlEntryExtensions + * } + * </pre> + */ + public class RevDetails : Asn1Encodable { - private readonly CertTemplate certDetails; - private readonly X509Extensions crlEntryDetails; + public static RevDetails GetInstance(object obj) + { + if (obj is RevDetails revDetails) + return revDetails; - private RevDetails(Asn1Sequence seq) - { - certDetails = CertTemplate.GetInstance(seq[0]); - crlEntryDetails = seq.Count <= 1 - ? null - : X509Extensions.GetInstance(seq[1]); - } + if (obj != null) + return new RevDetails(Asn1Sequence.GetInstance(obj)); - public static RevDetails GetInstance(object obj) - { - if (obj is RevDetails) - return (RevDetails)obj; + return null; + } - if (obj is Asn1Sequence) - return new RevDetails((Asn1Sequence)obj); + private readonly CertTemplate m_certDetails; + private readonly X509Extensions m_crlEntryDetails; - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + private RevDetails(Asn1Sequence seq) + { + m_certDetails = CertTemplate.GetInstance(seq[0]); + + if (seq.Count > 1) + { + m_crlEntryDetails = X509Extensions.GetInstance(seq[1]); + } } public RevDetails(CertTemplate certDetails) - : this(certDetails, null) + : this(certDetails, null) { } public RevDetails(CertTemplate certDetails, X509Extensions crlEntryDetails) { - this.certDetails = certDetails; - this.crlEntryDetails = crlEntryDetails; + m_certDetails = certDetails; + m_crlEntryDetails = crlEntryDetails; } - public virtual CertTemplate CertDetails - { - get { return certDetails; } - } + public virtual CertTemplate CertDetails => m_certDetails; - public virtual X509Extensions CrlEntryDetails - { - get { return crlEntryDetails; } - } + public virtual X509Extensions CrlEntryDetails => m_crlEntryDetails; /** * <pre> @@ -67,8 +72,8 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(certDetails); - v.AddOptional(crlEntryDetails); + Asn1EncodableVector v = new Asn1EncodableVector(m_certDetails); + v.AddOptional(m_crlEntryDetails); return new DerSequence(v); } } diff --git a/crypto/src/asn1/cmp/RevRepContent.cs b/crypto/src/asn1/cmp/RevRepContent.cs index 4b3f82b96..841b3cf94 100644 --- a/crypto/src/asn1/cmp/RevRepContent.cs +++ b/crypto/src/asn1/cmp/RevRepContent.cs @@ -1,21 +1,43 @@ -using System; - using Org.BouncyCastle.Asn1.Crmf; using Org.BouncyCastle.Asn1.X509; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1.Cmp { - public class RevRepContent + /** + * <pre> + * RevRepContent ::= SEQUENCE { + * status SEQUENCE SIZE (1..MAX) OF PKIStatusInfo, + * -- in same order as was sent in RevReqContent + * revCerts [0] SEQUENCE SIZE (1..MAX) OF CertId + * OPTIONAL, + * -- IDs for which revocation was requested + * -- (same order as status) + * crls [1] SEQUENCE SIZE (1..MAX) OF CertificateList OPTIONAL + * -- the resulting CRLs (there may be more than one) + * } + *</pre> + */ + public class RevRepContent : Asn1Encodable { - private readonly Asn1Sequence status; - private readonly Asn1Sequence revCerts; - private readonly Asn1Sequence crls; + public static RevRepContent GetInstance(object obj) + { + if (obj is RevRepContent revRepContent) + return revRepContent; + + if (obj != null) + return new RevRepContent(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private readonly Asn1Sequence m_status; + private readonly Asn1Sequence m_revCerts; + private readonly Asn1Sequence m_crls; private RevRepContent(Asn1Sequence seq) { - status = Asn1Sequence.GetInstance(seq[0]); + m_status = Asn1Sequence.GetInstance(seq[0]); for (int pos = 1; pos < seq.Count; ++pos) { @@ -23,60 +45,34 @@ namespace Org.BouncyCastle.Asn1.Cmp if (tObj.TagNo == 0) { - revCerts = Asn1Sequence.GetInstance(tObj, true); + m_revCerts = Asn1Sequence.GetInstance(tObj, true); } else { - crls = Asn1Sequence.GetInstance(tObj, true); + m_crls = Asn1Sequence.GetInstance(tObj, true); } } } - public static RevRepContent GetInstance(object obj) - { - if (obj is RevRepContent) - return (RevRepContent)obj; - - if (obj is Asn1Sequence) - return new RevRepContent((Asn1Sequence)obj); - - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); - } - public virtual PkiStatusInfo[] GetStatus() { - PkiStatusInfo[] results = new PkiStatusInfo[status.Count]; - for (int i = 0; i != results.Length; ++i) - { - results[i] = PkiStatusInfo.GetInstance(status[i]); - } - return results; + return m_status.MapElements(PkiStatusInfo.GetInstance); } public virtual CertId[] GetRevCerts() { - if (revCerts == null) + if (m_revCerts == null) return null; - CertId[] results = new CertId[revCerts.Count]; - for (int i = 0; i != results.Length; ++i) - { - results[i] = CertId.GetInstance(revCerts[i]); - } - return results; + return m_revCerts.MapElements(CertId.GetInstance); } public virtual CertificateList[] GetCrls() { - if (crls == null) + if (m_crls == null) return null; - CertificateList[] results = new CertificateList[crls.Count]; - for (int i = 0; i != results.Length; ++i) - { - results[i] = CertificateList.GetInstance(crls[i]); - } - return results; + return m_crls.MapElements(CertificateList.GetInstance); } /** @@ -95,9 +91,9 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(status); - v.AddOptionalTagged(true, 0, revCerts); - v.AddOptionalTagged(true, 1, crls); + Asn1EncodableVector v = new Asn1EncodableVector(m_status); + v.AddOptionalTagged(true, 0, m_revCerts); + v.AddOptionalTagged(true, 1, m_crls); return new DerSequence(v); } } diff --git a/crypto/src/asn1/cmp/RevRepContentBuilder.cs b/crypto/src/asn1/cmp/RevRepContentBuilder.cs index cc17d1d4c..f23bed8b5 100644 --- a/crypto/src/asn1/cmp/RevRepContentBuilder.cs +++ b/crypto/src/asn1/cmp/RevRepContentBuilder.cs @@ -7,29 +7,29 @@ namespace Org.BouncyCastle.Asn1.Cmp { public class RevRepContentBuilder { - private readonly Asn1EncodableVector status = new Asn1EncodableVector(); - private readonly Asn1EncodableVector revCerts = new Asn1EncodableVector(); - private readonly Asn1EncodableVector crls = new Asn1EncodableVector(); + private readonly Asn1EncodableVector m_status = new Asn1EncodableVector(); + private readonly Asn1EncodableVector m_revCerts = new Asn1EncodableVector(); + private readonly Asn1EncodableVector m_crls = new Asn1EncodableVector(); public virtual RevRepContentBuilder Add(PkiStatusInfo status) { - this.status.Add(status); + m_status.Add(status); return this; } public virtual RevRepContentBuilder Add(PkiStatusInfo status, CertId certId) { - if (this.status.Count != this.revCerts.Count) + if (m_status.Count != m_revCerts.Count) throw new InvalidOperationException("status and revCerts sequence must be in common order"); - this.status.Add(status); - this.revCerts.Add(certId); + m_status.Add(status); + m_revCerts.Add(certId); return this; } public virtual RevRepContentBuilder AddCrl(CertificateList crl) { - this.crls.Add(crl); + m_crls.Add(crl); return this; } @@ -37,16 +37,16 @@ namespace Org.BouncyCastle.Asn1.Cmp { Asn1EncodableVector v = new Asn1EncodableVector(); - v.Add(new DerSequence(status)); + v.Add(new DerSequence(m_status)); - if (revCerts.Count != 0) + if (m_revCerts.Count != 0) { - v.Add(new DerTaggedObject(true, 0, new DerSequence(revCerts))); + v.Add(new DerTaggedObject(true, 0, new DerSequence(m_revCerts))); } - if (crls.Count != 0) + if (m_crls.Count != 0) { - v.Add(new DerTaggedObject(true, 1, new DerSequence(crls))); + v.Add(new DerTaggedObject(true, 1, new DerSequence(m_crls))); } return RevRepContent.GetInstance(new DerSequence(v)); diff --git a/crypto/src/asn1/cmp/RevReqContent.cs b/crypto/src/asn1/cmp/RevReqContent.cs index 1522d3789..c390530a8 100644 --- a/crypto/src/asn1/cmp/RevReqContent.cs +++ b/crypto/src/asn1/cmp/RevReqContent.cs @@ -7,37 +7,37 @@ namespace Org.BouncyCastle.Asn1.Cmp public class RevReqContent : Asn1Encodable { - private readonly Asn1Sequence content; - - private RevReqContent(Asn1Sequence seq) - { - content = seq; - } + public static RevReqContent GetInstance(object obj) + { + if (obj is RevReqContent revReqContent) + return revReqContent; - public static RevReqContent GetInstance(object obj) - { - if (obj is RevReqContent) - return (RevReqContent)obj; + if (obj != null) + return new RevReqContent(Asn1Sequence.GetInstance(obj)); - if (obj is Asn1Sequence) - return new RevReqContent((Asn1Sequence)obj); + return null; + } - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + private readonly Asn1Sequence m_content; + + private RevReqContent(Asn1Sequence seq) + { + m_content = seq; } - public RevReqContent(params RevDetails[] revDetails) + public RevReqContent(RevDetails revDetails) + { + m_content = new DerSequence(revDetails); + } + + public RevReqContent(params RevDetails[] revDetailsArray) { - this.content = new DerSequence(revDetails); + m_content = new DerSequence(revDetailsArray); } public virtual RevDetails[] ToRevDetailsArray() { - RevDetails[] result = new RevDetails[content.Count]; - for (int i = 0; i != result.Length; ++i) - { - result[i] = RevDetails.GetInstance(content[i]); - } - return result; + return m_content.MapElements(RevDetails.GetInstance); } /** @@ -48,7 +48,7 @@ namespace Org.BouncyCastle.Asn1.Cmp */ public override Asn1Object ToAsn1Object() { - return content; + return m_content; } } } diff --git a/crypto/src/asn1/cmp/RootCaKeyUpdateContent.cs b/crypto/src/asn1/cmp/RootCaKeyUpdateContent.cs new file mode 100644 index 000000000..696b08b94 --- /dev/null +++ b/crypto/src/asn1/cmp/RootCaKeyUpdateContent.cs @@ -0,0 +1,91 @@ +using System; + +namespace Org.BouncyCastle.Asn1.Cmp +{ + /** + * GenMsg: {id-it 20}, RootCaCertValue | < absent > + * GenRep: {id-it 18}, RootCaKeyUpdateContent | < absent > + * <p> + * RootCaCertValue ::= CMPCertificate + * </p><p> + * RootCaKeyUpdateValue ::= RootCaKeyUpdateContent + * </p><p> + * RootCaKeyUpdateContent ::= SEQUENCE { + * newWithNew CMPCertificate, + * newWithOld [0] CMPCertificate OPTIONAL, + * oldWithNew [1] CMPCertificate OPTIONAL + * } + * </p> + */ + public class RootCaKeyUpdateContent + : Asn1Encodable + { + public static RootCaKeyUpdateContent GetInstance(object obj) + { + if (obj is RootCaKeyUpdateContent rootCaKeyUpdateContent) + return rootCaKeyUpdateContent; + + if (obj != null) + return new RootCaKeyUpdateContent(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private readonly CmpCertificate m_newWithNew; + private readonly CmpCertificate m_newWithOld; + private readonly CmpCertificate m_oldWithNew; + + public RootCaKeyUpdateContent(CmpCertificate newWithNew, CmpCertificate newWithOld, CmpCertificate oldWithNew) + { + if (newWithNew == null) + throw new ArgumentNullException(nameof(newWithNew)); + + m_newWithNew = newWithNew; + m_newWithOld = newWithOld; + m_oldWithNew = oldWithNew; + } + + private RootCaKeyUpdateContent(Asn1Sequence seq) + { + if (seq.Count < 1 || seq.Count > 3) + throw new ArgumentException("expected sequence of 1 to 3 elements only"); + + CmpCertificate newWithNew; + CmpCertificate newWithOld = null; + CmpCertificate oldWithNew = null; + + newWithNew = CmpCertificate.GetInstance(seq[0]); + + for (int pos = 1; pos < seq.Count; ++pos) + { + Asn1TaggedObject ato = Asn1TaggedObject.GetInstance(seq[pos]); + if (ato.TagNo == 0) + { + newWithOld = CmpCertificate.GetInstance(ato, true); + } + else if (ato.TagNo == 1) + { + oldWithNew = CmpCertificate.GetInstance(ato, true); + } + } + + m_newWithNew = newWithNew; + m_newWithOld = newWithOld; + m_oldWithNew = oldWithNew; + } + + public virtual CmpCertificate NewWithNew => m_newWithNew; + + public virtual CmpCertificate NewWithOld => m_newWithOld; + + public virtual CmpCertificate OldWithNew => m_oldWithNew; + + public override Asn1Object ToAsn1Object() + { + Asn1EncodableVector v = new Asn1EncodableVector(m_newWithNew); + v.AddOptionalTagged(true, 0, m_newWithOld); + v.AddOptionalTagged(true, 1, m_oldWithNew); + return new DerSequence(v); + } + } +} diff --git a/crypto/src/asn1/cms/CMSObjectIdentifiers.cs b/crypto/src/asn1/cms/CMSObjectIdentifiers.cs index 2ad0a3c7c..6f4f8fb5e 100644 --- a/crypto/src/asn1/cms/CMSObjectIdentifiers.cs +++ b/crypto/src/asn1/cms/CMSObjectIdentifiers.cs @@ -13,7 +13,8 @@ namespace Org.BouncyCastle.Asn1.Cms public static readonly DerObjectIdentifier AuthenticatedData = PkcsObjectIdentifiers.IdCTAuthData; public static readonly DerObjectIdentifier CompressedData = PkcsObjectIdentifiers.IdCTCompressedData; public static readonly DerObjectIdentifier AuthEnvelopedData = PkcsObjectIdentifiers.IdCTAuthEnvelopedData; - public static readonly DerObjectIdentifier timestampedData = PkcsObjectIdentifiers.IdCTTimestampedData; + public static readonly DerObjectIdentifier TimestampedData = PkcsObjectIdentifiers.IdCTTimestampedData; + public static readonly DerObjectIdentifier ZlibCompress = PkcsObjectIdentifiers.IdAlgZlibCompress; /** * The other Revocation Info arc diff --git a/crypto/src/asn1/cms/KEKIdentifier.cs b/crypto/src/asn1/cms/KEKIdentifier.cs index a42217440..36ab94f52 100644 --- a/crypto/src/asn1/cms/KEKIdentifier.cs +++ b/crypto/src/asn1/cms/KEKIdentifier.cs @@ -8,12 +8,12 @@ namespace Org.BouncyCastle.Asn1.Cms : Asn1Encodable { private Asn1OctetString keyIdentifier; - private DerGeneralizedTime date; + private Asn1GeneralizedTime date; private OtherKeyAttribute other; public KekIdentifier( byte[] keyIdentifier, - DerGeneralizedTime date, + Asn1GeneralizedTime date, OtherKeyAttribute other) { this.keyIdentifier = new DerOctetString(keyIdentifier); @@ -31,9 +31,9 @@ namespace Org.BouncyCastle.Asn1.Cms case 1: break; case 2: - if (seq[1] is DerGeneralizedTime) + if (seq[1] is Asn1GeneralizedTime) { - date = (DerGeneralizedTime) seq[1]; + date = (Asn1GeneralizedTime) seq[1]; } else { @@ -41,7 +41,7 @@ namespace Org.BouncyCastle.Asn1.Cms } break; case 3: - date = (DerGeneralizedTime) seq[1]; + date = (Asn1GeneralizedTime) seq[1]; other = OtherKeyAttribute.GetInstance(seq[2]); break; default: @@ -88,7 +88,7 @@ namespace Org.BouncyCastle.Asn1.Cms get { return keyIdentifier; } } - public DerGeneralizedTime Date + public Asn1GeneralizedTime Date { get { return date; } } diff --git a/crypto/src/asn1/cms/RecipientKeyIdentifier.cs b/crypto/src/asn1/cms/RecipientKeyIdentifier.cs index 995ddab51..dea9ce09d 100644 --- a/crypto/src/asn1/cms/RecipientKeyIdentifier.cs +++ b/crypto/src/asn1/cms/RecipientKeyIdentifier.cs @@ -8,12 +8,12 @@ namespace Org.BouncyCastle.Asn1.Cms : Asn1Encodable { private Asn1OctetString subjectKeyIdentifier; - private DerGeneralizedTime date; + private Asn1GeneralizedTime date; private OtherKeyAttribute other; public RecipientKeyIdentifier( Asn1OctetString subjectKeyIdentifier, - DerGeneralizedTime date, + Asn1GeneralizedTime date, OtherKeyAttribute other) { this.subjectKeyIdentifier = subjectKeyIdentifier; @@ -29,7 +29,7 @@ namespace Org.BouncyCastle.Asn1.Cms public RecipientKeyIdentifier( byte[] subjectKeyIdentifier, - DerGeneralizedTime date, + Asn1GeneralizedTime date, OtherKeyAttribute other) { this.subjectKeyIdentifier = new DerOctetString(subjectKeyIdentifier); @@ -48,9 +48,9 @@ namespace Org.BouncyCastle.Asn1.Cms case 1: break; case 2: - if (seq[1] is DerGeneralizedTime) + if (seq[1] is Asn1GeneralizedTime) { - date = (DerGeneralizedTime) seq[1]; + date = (Asn1GeneralizedTime)seq[1]; } else { @@ -58,7 +58,7 @@ namespace Org.BouncyCastle.Asn1.Cms } break; case 3: - date = (DerGeneralizedTime) seq[1]; + date = (Asn1GeneralizedTime)seq[1]; other = OtherKeyAttribute.GetInstance(seq[2]); break; default: @@ -105,7 +105,7 @@ namespace Org.BouncyCastle.Asn1.Cms get { return subjectKeyIdentifier; } } - public DerGeneralizedTime Date + public Asn1GeneralizedTime Date { get { return date; } } diff --git a/crypto/src/asn1/cms/Time.cs b/crypto/src/asn1/cms/Time.cs index 47e284e69..67c73285b 100644 --- a/crypto/src/asn1/cms/Time.cs +++ b/crypto/src/asn1/cms/Time.cs @@ -22,7 +22,7 @@ namespace Org.BouncyCastle.Asn1.Cms { if (time == null) throw new ArgumentNullException("time"); - if (!(time is DerUtcTime) && !(time is DerGeneralizedTime)) + if (!(time is Asn1UtcTime) && !(time is Asn1GeneralizedTime)) throw new ArgumentException("unknown object passed to Time"); this.time = time; @@ -33,8 +33,7 @@ namespace Org.BouncyCastle.Asn1.Cms * and 2049 a UTCTime object is Generated, otherwise a GeneralizedTime * is used. */ - public Time( - DateTime date) + public Time(DateTime date) { DateTime d = date.ToUniversalTime(); @@ -48,15 +47,16 @@ namespace Org.BouncyCastle.Asn1.Cms } } - public static Time GetInstance( - object obj) + public static Time GetInstance(object obj) { - if (obj == null || obj is Time) - return (Time)obj; - if (obj is DerUtcTime) - return new Time((DerUtcTime)obj); - if (obj is DerGeneralizedTime) - return new Time((DerGeneralizedTime)obj); + if (obj == null) + return null; + if (obj is Time time) + return time; + if (obj is Asn1UtcTime utcTime) + return new Time(utcTime); + if (obj is Asn1GeneralizedTime generalizedTime) + return new Time(generalizedTime); throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); } @@ -65,14 +65,10 @@ namespace Org.BouncyCastle.Asn1.Cms { get { - if (time is DerUtcTime) - { - return ((DerUtcTime)time).AdjustedTimeString; - } - else - { - return ((DerGeneralizedTime)time).GetTime(); - } + if (time is Asn1UtcTime utcTime) + return utcTime.AdjustedTimeString; + + return ((Asn1GeneralizedTime)time).GetTime(); } } @@ -82,12 +78,10 @@ namespace Org.BouncyCastle.Asn1.Cms { try { - if (time is DerUtcTime) - { - return ((DerUtcTime)time).ToAdjustedDateTime(); - } + if (time is Asn1UtcTime utcTime) + return utcTime.ToAdjustedDateTime(); - return ((DerGeneralizedTime)time).ToDateTime(); + return ((Asn1GeneralizedTime)time).ToDateTime(); } catch (FormatException e) { diff --git a/crypto/src/asn1/crmf/EncryptedKey.cs b/crypto/src/asn1/crmf/EncryptedKey.cs index 850fbd219..d4ff250c5 100644 --- a/crypto/src/asn1/crmf/EncryptedKey.cs +++ b/crypto/src/asn1/crmf/EncryptedKey.cs @@ -1,58 +1,44 @@ -using System; - -using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.Cms; namespace Org.BouncyCastle.Asn1.Crmf { public class EncryptedKey : Asn1Encodable, IAsn1Choice { - private readonly EnvelopedData envelopedData; - private readonly EncryptedValue encryptedValue; - - public static EncryptedKey GetInstance(object o) + public static EncryptedKey GetInstance(object obj) { - if (o is EncryptedKey) - { - return (EncryptedKey)o; - } - else if (o is Asn1TaggedObject) - { - return new EncryptedKey(EnvelopedData.GetInstance((Asn1TaggedObject)o, false)); - } - else if (o is EncryptedValue) - { - return new EncryptedKey((EncryptedValue)o); - } - else - { - return new EncryptedKey(EncryptedValue.GetInstance(o)); - } + if (obj is EncryptedKey encryptedKey) + return encryptedKey; + + if (obj is Asn1TaggedObject taggedObject) + return new EncryptedKey(EnvelopedData.GetInstance(taggedObject, false)); + + return new EncryptedKey(EncryptedValue.GetInstance(obj)); } + private readonly EnvelopedData m_envelopedData; + private readonly EncryptedValue m_encryptedValue; + public EncryptedKey(EnvelopedData envelopedData) { - this.envelopedData = envelopedData; + m_envelopedData = envelopedData; } public EncryptedKey(EncryptedValue encryptedValue) { - this.encryptedValue = encryptedValue; + m_encryptedValue = encryptedValue; } - public virtual bool IsEncryptedValue - { - get { return encryptedValue != null; } - } + public virtual bool IsEncryptedValue => m_encryptedValue != null; public virtual Asn1Encodable Value { get { - if (encryptedValue != null) - return encryptedValue; + if (m_encryptedValue != null) + return m_encryptedValue; - return envelopedData; + return m_envelopedData; } } @@ -67,12 +53,10 @@ namespace Org.BouncyCastle.Asn1.Crmf */ public override Asn1Object ToAsn1Object() { - if (encryptedValue != null) - { - return encryptedValue.ToAsn1Object(); - } + if (m_encryptedValue != null) + return m_encryptedValue.ToAsn1Object(); - return new DerTaggedObject(false, 0, envelopedData); + return new DerTaggedObject(false, 0, m_envelopedData); } } } diff --git a/crypto/src/asn1/crmf/EncryptedValue.cs b/crypto/src/asn1/crmf/EncryptedValue.cs index 7c5cf18b4..950298504 100644 --- a/crypto/src/asn1/crmf/EncryptedValue.cs +++ b/crypto/src/asn1/crmf/EncryptedValue.cs @@ -7,48 +7,10 @@ namespace Org.BouncyCastle.Asn1.Crmf public class EncryptedValue : Asn1Encodable { - private readonly AlgorithmIdentifier intendedAlg; - private readonly AlgorithmIdentifier symmAlg; - private readonly DerBitString encSymmKey; - private readonly AlgorithmIdentifier keyAlg; - private readonly Asn1OctetString valueHint; - private readonly DerBitString encValue; - - private EncryptedValue(Asn1Sequence seq) - { - int index = 0; - while (seq[index] is Asn1TaggedObject) - { - Asn1TaggedObject tObj = (Asn1TaggedObject)seq[index]; - - switch (tObj.TagNo) - { - case 0: - intendedAlg = AlgorithmIdentifier.GetInstance(tObj, false); - break; - case 1: - symmAlg = AlgorithmIdentifier.GetInstance(tObj, false); - break; - case 2: - encSymmKey = DerBitString.GetInstance(tObj, false); - break; - case 3: - keyAlg = AlgorithmIdentifier.GetInstance(tObj, false); - break; - case 4: - valueHint = Asn1OctetString.GetInstance(tObj, false); - break; - } - ++index; - } - - encValue = DerBitString.GetInstance(seq[index]); - } - public static EncryptedValue GetInstance(object obj) { - if (obj is EncryptedValue) - return (EncryptedValue)obj; + if (obj is EncryptedValue encryptedValue) + return encryptedValue; if (obj != null) return new EncryptedValue(Asn1Sequence.GetInstance(obj)); @@ -56,59 +18,71 @@ namespace Org.BouncyCastle.Asn1.Crmf return null; } - public EncryptedValue( - AlgorithmIdentifier intendedAlg, - AlgorithmIdentifier symmAlg, - DerBitString encSymmKey, - AlgorithmIdentifier keyAlg, - Asn1OctetString valueHint, - DerBitString encValue) + private readonly AlgorithmIdentifier m_intendedAlg; + private readonly AlgorithmIdentifier m_symmAlg; + private readonly DerBitString m_encSymmKey; + private readonly AlgorithmIdentifier m_keyAlg; + private readonly Asn1OctetString m_valueHint; + private readonly DerBitString m_encValue; + + private EncryptedValue(Asn1Sequence seq) { - if (encValue == null) + int index = 0; + while (seq[index] is Asn1TaggedObject tObj) { - throw new ArgumentNullException("encValue"); + switch (tObj.TagNo) + { + case 0: + m_intendedAlg = AlgorithmIdentifier.GetInstance(tObj, false); + break; + case 1: + m_symmAlg = AlgorithmIdentifier.GetInstance(tObj, false); + break; + case 2: + m_encSymmKey = DerBitString.GetInstance(tObj, false); + break; + case 3: + m_keyAlg = AlgorithmIdentifier.GetInstance(tObj, false); + break; + case 4: + m_valueHint = Asn1OctetString.GetInstance(tObj, false); + break; + } + ++index; } - this.intendedAlg = intendedAlg; - this.symmAlg = symmAlg; - this.encSymmKey = encSymmKey; - this.keyAlg = keyAlg; - this.valueHint = valueHint; - this.encValue = encValue; + m_encValue = DerBitString.GetInstance(seq[index]); } - public virtual AlgorithmIdentifier IntendedAlg + public EncryptedValue(AlgorithmIdentifier intendedAlg, AlgorithmIdentifier symmAlg, DerBitString encSymmKey, + AlgorithmIdentifier keyAlg, Asn1OctetString valueHint, DerBitString encValue) { - get { return intendedAlg; } + if (encValue == null) + throw new ArgumentNullException(nameof(encValue)); + + m_intendedAlg = intendedAlg; + m_symmAlg = symmAlg; + m_encSymmKey = encSymmKey; + m_keyAlg = keyAlg; + m_valueHint = valueHint; + m_encValue = encValue; } - public virtual AlgorithmIdentifier SymmAlg - { - get { return symmAlg; } - } + public virtual AlgorithmIdentifier IntendedAlg => m_intendedAlg; - public virtual DerBitString EncSymmKey - { - get { return encSymmKey; } - } + public virtual AlgorithmIdentifier SymmAlg => m_symmAlg; - public virtual AlgorithmIdentifier KeyAlg - { - get { return keyAlg; } - } + public virtual DerBitString EncSymmKey => m_encSymmKey; - public virtual Asn1OctetString ValueHint - { - get { return valueHint; } - } + public virtual AlgorithmIdentifier KeyAlg => m_keyAlg; - public virtual DerBitString EncValue - { - get { return encValue; } - } + public virtual Asn1OctetString ValueHint => m_valueHint; + + public virtual DerBitString EncValue => m_encValue; /** * <pre> + * (IMPLICIT TAGS) * EncryptedValue ::= SEQUENCE { * intendedAlg [0] AlgorithmIdentifier OPTIONAL, * -- the intended algorithm for which the value will be used @@ -131,12 +105,12 @@ namespace Org.BouncyCastle.Asn1.Crmf public override Asn1Object ToAsn1Object() { Asn1EncodableVector v = new Asn1EncodableVector(); - v.AddOptionalTagged(false, 0, intendedAlg); - v.AddOptionalTagged(false, 1, symmAlg); - v.AddOptionalTagged(false, 2, encSymmKey); - v.AddOptionalTagged(false, 3, keyAlg); - v.AddOptionalTagged(false, 4, valueHint); - v.Add(encValue); + v.AddOptionalTagged(false, 0, m_intendedAlg); + v.AddOptionalTagged(false, 1, m_symmAlg); + v.AddOptionalTagged(false, 2, m_encSymmKey); + v.AddOptionalTagged(false, 3, m_keyAlg); + v.AddOptionalTagged(false, 4, m_valueHint); + v.Add(m_encValue); return new DerSequence(v); } } diff --git a/crypto/src/asn1/crmf/PKIPublicationInfo.cs b/crypto/src/asn1/crmf/PKIPublicationInfo.cs index a7d2bc603..c855a7d28 100644 --- a/crypto/src/asn1/crmf/PKIPublicationInfo.cs +++ b/crypto/src/asn1/crmf/PKIPublicationInfo.cs @@ -1,48 +1,91 @@ -using System; - -using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Math; namespace Org.BouncyCastle.Asn1.Crmf { + /** + * <pre> + * PKIPublicationInfo ::= SEQUENCE { + * action INTEGER { + * dontPublish (0), + * pleasePublish (1) }, + * pubInfos SEQUENCE SIZE (1..MAX) OF SinglePubInfo OPTIONAL } + * -- pubInfos MUST NOT be present if action is "dontPublish" + * -- (if action is "pleasePublish" and pubInfos is omitted, + * -- "dontCare" is assumed) + * </pre> + */ public class PkiPublicationInfo : Asn1Encodable { - private readonly DerInteger action; - private readonly Asn1Sequence pubInfos; + public static readonly DerInteger DontPublish = new DerInteger(0); + public static readonly DerInteger PleasePublish = new DerInteger(1); + + public static PkiPublicationInfo GetInstance(object obj) + { + if (obj is PkiPublicationInfo pkiPublicationInfo) + return pkiPublicationInfo; + + if (obj != null) + return new PkiPublicationInfo(Asn1Sequence.GetInstance(obj)); + + return null; + } + + private readonly DerInteger m_action; + private readonly Asn1Sequence m_pubInfos; private PkiPublicationInfo(Asn1Sequence seq) { - action = DerInteger.GetInstance(seq[0]); - pubInfos = Asn1Sequence.GetInstance(seq[1]); + m_action = DerInteger.GetInstance(seq[0]); + if (seq.Count > 1) + { + m_pubInfos = Asn1Sequence.GetInstance(seq[1]); + } } - public static PkiPublicationInfo GetInstance(object obj) + public PkiPublicationInfo(BigInteger action) + : this(new DerInteger(action)) { - if (obj is PkiPublicationInfo) - return (PkiPublicationInfo)obj; + } - if (obj is Asn1Sequence) - return new PkiPublicationInfo((Asn1Sequence)obj); + public PkiPublicationInfo(DerInteger action) + { + m_action = action; + } - throw new ArgumentException("Invalid object: " + Platform.GetTypeName(obj), "obj"); + /** + * Constructor with a single pubInfo, assumes pleasePublish as the action. + * + * @param pubInfo the pubInfo to be published (can be null if don't care is required). + */ + public PkiPublicationInfo(SinglePubInfo pubInfo) + : this(pubInfo != null ? new SinglePubInfo[1]{ pubInfo } : null) + { } - public virtual DerInteger Action + /** + * Constructor with multiple pubInfo, assumes pleasePublish as the action. + * + * @param pubInfos the pubInfos to be published (can be null if don't care is required). + */ + public PkiPublicationInfo(SinglePubInfo[] pubInfos) { - get { return action; } + m_action = PleasePublish; + + if (pubInfos != null) + { + m_pubInfos = new DerSequence(pubInfos); + } } + public virtual DerInteger Action => m_action; + public virtual SinglePubInfo[] GetPubInfos() { - if (pubInfos == null) + if (m_pubInfos == null) return null; - SinglePubInfo[] results = new SinglePubInfo[pubInfos.Count]; - for (int i = 0; i != results.Length; ++i) - { - results[i] = SinglePubInfo.GetInstance(pubInfos[i]); - } - return results; + return m_pubInfos.MapElements(SinglePubInfo.GetInstance); } /** @@ -60,7 +103,10 @@ namespace Org.BouncyCastle.Asn1.Crmf */ public override Asn1Object ToAsn1Object() { - return new DerSequence(action, pubInfos); + if (m_pubInfos == null) + return new DerSequence(m_action); + + return new DerSequence(m_action, m_pubInfos); } } } diff --git a/crypto/src/asn1/cryptlib/CryptlibObjectIdentifiers.cs b/crypto/src/asn1/cryptlib/CryptlibObjectIdentifiers.cs new file mode 100644 index 000000000..e7208bab2 --- /dev/null +++ b/crypto/src/asn1/cryptlib/CryptlibObjectIdentifiers.cs @@ -0,0 +1,11 @@ +namespace Org.BouncyCastle.Asn1.Cryptlib +{ + internal class CryptlibObjectIdentifiers + { + internal static readonly DerObjectIdentifier cryptlib = new DerObjectIdentifier("1.3.6.1.4.1.3029"); + + internal static readonly DerObjectIdentifier ecc = cryptlib.Branch("1.5"); + + internal static readonly DerObjectIdentifier curvey25519 = ecc.Branch("1"); + } +} diff --git a/crypto/src/asn1/cryptopro/CryptoProObjectIdentifiers.cs b/crypto/src/asn1/cryptopro/CryptoProObjectIdentifiers.cs index e2f2c1848..5e3cb4781 100644 --- a/crypto/src/asn1/cryptopro/CryptoProObjectIdentifiers.cs +++ b/crypto/src/asn1/cryptopro/CryptoProObjectIdentifiers.cs @@ -13,7 +13,9 @@ namespace Org.BouncyCastle.Asn1.CryptoPro public static readonly DerObjectIdentifier GostR3411 = new DerObjectIdentifier(GostID + ".9"); public static readonly DerObjectIdentifier GostR3411Hmac = new DerObjectIdentifier(GostID + ".10"); - public static readonly DerObjectIdentifier GostR28147Cbc = new DerObjectIdentifier(GostID + ".21"); + public static readonly DerObjectIdentifier GostR28147Gcfb = new DerObjectIdentifier(GostID + ".21"); + [Obsolete("Use 'GostR28147Gcfb' instead")] + public static readonly DerObjectIdentifier GostR28147Cbc = GostR28147Gcfb; public static readonly DerObjectIdentifier ID_Gost28147_89_CryptoPro_A_ParamSet = new DerObjectIdentifier(GostID + ".31.1"); @@ -47,5 +49,9 @@ namespace Org.BouncyCastle.Asn1.CryptoPro public static readonly DerObjectIdentifier GostElSgDH3410Default = new DerObjectIdentifier(GostID + ".36.0"); public static readonly DerObjectIdentifier GostElSgDH3410x1 = new DerObjectIdentifier(GostID + ".36.1"); + + public static readonly DerObjectIdentifier GostR3410x2001CryptoProESDH = new DerObjectIdentifier(GostID + ".96"); + + public static readonly DerObjectIdentifier GostR3410x2001DH = new DerObjectIdentifier(GostID + ".98"); } } diff --git a/crypto/src/asn1/esf/CrlIdentifier.cs b/crypto/src/asn1/esf/CrlIdentifier.cs index a8e40c870..44c99170c 100644 --- a/crypto/src/asn1/esf/CrlIdentifier.cs +++ b/crypto/src/asn1/esf/CrlIdentifier.cs @@ -1,5 +1,5 @@ using System; - +using System.Reflection; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Math; using Org.BouncyCastle.Utilities; @@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Asn1.Esf : Asn1Encodable { private readonly X509Name crlIssuer; - private readonly DerUtcTime crlIssuedTime; + private readonly Asn1UtcTime crlIssuedTime; private readonly DerInteger crlNumber; public static CrlIdentifier GetInstance( @@ -48,7 +48,7 @@ namespace Org.BouncyCastle.Asn1.Esf throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); this.crlIssuer = X509Name.GetInstance(seq[0]); - this.crlIssuedTime = DerUtcTime.GetInstance(seq[1]); + this.crlIssuedTime = Asn1UtcTime.GetInstance(seq[1]); if (seq.Count > 2) { @@ -56,31 +56,36 @@ namespace Org.BouncyCastle.Asn1.Esf } } - public CrlIdentifier( - X509Name crlIssuer, - DateTime crlIssuedTime) - : this(crlIssuer, crlIssuedTime, null) + public CrlIdentifier(X509Name crlIssuer, DateTime crlIssuedTime) + : this(crlIssuer, crlIssuedTime, null) { } - public CrlIdentifier( - X509Name crlIssuer, - DateTime crlIssuedTime, - BigInteger crlNumber) + public CrlIdentifier(X509Name crlIssuer, DateTime crlIssuedTime, BigInteger crlNumber) + : this(crlIssuer, new Asn1UtcTime(crlIssuedTime), crlNumber) { - if (crlIssuer == null) - throw new ArgumentNullException("crlIssuer"); + } - this.crlIssuer = crlIssuer; - this.crlIssuedTime = new DerUtcTime(crlIssuedTime); + public CrlIdentifier(X509Name crlIssuer, Asn1UtcTime crlIssuedTime) + : this(crlIssuer, crlIssuedTime, null) + { + } - if (crlNumber != null) - { - this.crlNumber = new DerInteger(crlNumber); - } - } + public CrlIdentifier(X509Name crlIssuer, Asn1UtcTime crlIssuedTime, BigInteger crlNumber) + { + if (crlIssuer == null) + throw new ArgumentNullException(nameof(crlIssuer)); + + this.crlIssuer = crlIssuer; + this.crlIssuedTime = crlIssuedTime; + + if (null != crlNumber) + { + this.crlNumber = new DerInteger(crlNumber); + } + } - public X509Name CrlIssuer + public X509Name CrlIssuer { get { return crlIssuer; } } diff --git a/crypto/src/asn1/esf/OcspIdentifier.cs b/crypto/src/asn1/esf/OcspIdentifier.cs index e65f1cfe7..fa7069aed 100644 --- a/crypto/src/asn1/esf/OcspIdentifier.cs +++ b/crypto/src/asn1/esf/OcspIdentifier.cs @@ -20,7 +20,7 @@ namespace Org.BouncyCastle.Asn1.Esf : Asn1Encodable { private readonly ResponderID ocspResponderID; - private readonly DerGeneralizedTime producedAt; + private readonly Asn1GeneralizedTime producedAt; public static OcspIdentifier GetInstance( object obj) @@ -46,21 +46,30 @@ namespace Org.BouncyCastle.Asn1.Esf throw new ArgumentException("Bad sequence size: " + seq.Count, "seq"); this.ocspResponderID = ResponderID.GetInstance(seq[0].ToAsn1Object()); - this.producedAt = (DerGeneralizedTime) seq[1].ToAsn1Object(); + this.producedAt = (Asn1GeneralizedTime)seq[1].ToAsn1Object(); } - public OcspIdentifier( - ResponderID ocspResponderID, - DateTime producedAt) + public OcspIdentifier(ResponderID ocspResponderID, DateTime producedAt) { if (ocspResponderID == null) - throw new ArgumentNullException(); + throw new ArgumentNullException(nameof(ocspResponderID)); this.ocspResponderID = ocspResponderID; - this.producedAt = new DerGeneralizedTime(producedAt); + this.producedAt = new Asn1GeneralizedTime(producedAt); } - public ResponderID OcspResponderID + public OcspIdentifier(ResponderID ocspResponderID, Asn1GeneralizedTime producedAt) + { + if (ocspResponderID == null) + throw new ArgumentNullException(nameof(ocspResponderID)); + if (producedAt == null) + throw new ArgumentNullException(nameof(producedAt)); + + this.ocspResponderID = ocspResponderID; + this.producedAt = producedAt; + } + + public ResponderID OcspResponderID { get { return ocspResponderID; } } diff --git a/crypto/src/asn1/isismtt/x509/DeclarationOfMajority.cs b/crypto/src/asn1/isismtt/x509/DeclarationOfMajority.cs index b82c9373d..c9c96cbda 100644 --- a/crypto/src/asn1/isismtt/x509/DeclarationOfMajority.cs +++ b/crypto/src/asn1/isismtt/x509/DeclarationOfMajority.cs @@ -64,7 +64,7 @@ namespace Org.BouncyCastle.Asn1.IsisMtt.X509 } public DeclarationOfMajority( - DerGeneralizedTime dateOfBirth) + Asn1GeneralizedTime dateOfBirth) { this.declaration = new DerTaggedObject(false, 2, dateOfBirth); } @@ -155,14 +155,14 @@ namespace Org.BouncyCastle.Asn1.IsisMtt.X509 } } - public virtual DerGeneralizedTime DateOfBirth + public virtual Asn1GeneralizedTime DateOfBirth { get { switch ((Choice) declaration.TagNo) { case Choice.DateOfBirth: - return DerGeneralizedTime.GetInstance(declaration, false); + return Asn1GeneralizedTime.GetInstance(declaration, false); default: return null; } diff --git a/crypto/src/asn1/misc/MiscObjectIdentifiers.cs b/crypto/src/asn1/misc/MiscObjectIdentifiers.cs index 54e4280b9..693c0eaba 100644 --- a/crypto/src/asn1/misc/MiscObjectIdentifiers.cs +++ b/crypto/src/asn1/misc/MiscObjectIdentifiers.cs @@ -40,15 +40,15 @@ namespace Org.BouncyCastle.Asn1.Misc // Novell // iso/itu(2) country(16) us(840) organization(1) novell(113719) // - public static readonly string Novell = "2.16.840.1.113719"; - public static readonly DerObjectIdentifier NovellSecurityAttribs = new DerObjectIdentifier(Novell + ".1.9.4.1"); + public static readonly DerObjectIdentifier Novell = new DerObjectIdentifier("2.16.840.1.113719"); + public static readonly DerObjectIdentifier NovellSecurityAttribs = Novell.Branch("1.9.4.1"); // // Entrust // iso(1) member-body(16) us(840) nortelnetworks(113533) entrust(7) // - public static readonly string Entrust = "1.2.840.113533.7"; - public static readonly DerObjectIdentifier EntrustVersionExtension = new DerObjectIdentifier(Entrust + ".65.0"); + public static readonly DerObjectIdentifier Entrust = new DerObjectIdentifier("1.2.840.113533.7"); + public static readonly DerObjectIdentifier EntrustVersionExtension = Entrust.Branch("65.0"); public static readonly DerObjectIdentifier cast5CBC = new DerObjectIdentifier(Entrust+ ".66.10"); @@ -89,10 +89,32 @@ namespace Org.BouncyCastle.Asn1.Misc public static readonly DerObjectIdentifier id_blake2s224 = blake2.Branch("2.7"); public static readonly DerObjectIdentifier id_blake2s256 = blake2.Branch("2.8"); + public static readonly DerObjectIdentifier blake3 = blake2.Branch("3"); + + public static readonly DerObjectIdentifier blake3_256 = blake3.Branch("8"); + // // Scrypt public static readonly DerObjectIdentifier id_scrypt = new DerObjectIdentifier("1.3.6.1.4.1.11591.4.11"); - public static readonly DerObjectIdentifier id_oracle_pkcs12_trusted_key_usage = new DerObjectIdentifier("2.16.840.1.113894.746875.1.1"); + // Composite key/signature oid - prototyping + // + // id-alg-composite OBJECT IDENTIFIER ::= { + // iso(1) identified-organization(3) dod(6) internet(1) private(4) + // enterprise(1) OpenCA(18227) Algorithms(2) id-alg-composite(1) } + public static readonly DerObjectIdentifier id_alg_composite = new DerObjectIdentifier("1.3.6.1.4.1.18227.2.1"); + + // -- To be replaced by IANA + // + //id-composite-key OBJECT IDENTIFIER ::= { + // + // joint-iso-itu-t(2) country(16) us(840) organization(1) entrust(114027) + // + // Algorithm(80) Composite(4) CompositeKey(1) + public static readonly DerObjectIdentifier id_composite_key = + new DerObjectIdentifier("2.16.840.1.114027.80.4.1"); + + public static readonly DerObjectIdentifier id_oracle_pkcs12_trusted_key_usage = + new DerObjectIdentifier("2.16.840.1.113894.746875.1.1"); } } diff --git a/crypto/src/asn1/ocsp/CrlID.cs b/crypto/src/asn1/ocsp/CrlID.cs index fc1e59d22..24dda4edf 100644 --- a/crypto/src/asn1/ocsp/CrlID.cs +++ b/crypto/src/asn1/ocsp/CrlID.cs @@ -7,7 +7,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp { private readonly DerIA5String crlUrl; private readonly DerInteger crlNum; - private readonly DerGeneralizedTime crlTime; + private readonly Asn1GeneralizedTime crlTime; // TODO Add GetInstance method(s) and make this private? public CrlID(Asn1Sequence seq) @@ -23,7 +23,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp crlNum = DerInteger.GetInstance(o, true); break; case 2: - crlTime = DerGeneralizedTime.GetInstance(o, true); + crlTime = Asn1GeneralizedTime.GetInstance(o, true); break; default: throw new ArgumentException("unknown tag number: " + o.TagNo); @@ -41,7 +41,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp get { return crlNum; } } - public DerGeneralizedTime CrlTime + public Asn1GeneralizedTime CrlTime { get { return crlTime; } } diff --git a/crypto/src/asn1/ocsp/ResponseData.cs b/crypto/src/asn1/ocsp/ResponseData.cs index a5769c0fa..dfb234bc1 100644 --- a/crypto/src/asn1/ocsp/ResponseData.cs +++ b/crypto/src/asn1/ocsp/ResponseData.cs @@ -13,7 +13,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp private readonly bool versionPresent; private readonly DerInteger version; private readonly ResponderID responderID; - private readonly DerGeneralizedTime producedAt; + private readonly Asn1GeneralizedTime producedAt; private readonly Asn1Sequence responses; private readonly X509Extensions responseExtensions; @@ -43,7 +43,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp public ResponseData( DerInteger version, ResponderID responderID, - DerGeneralizedTime producedAt, + Asn1GeneralizedTime producedAt, Asn1Sequence responses, X509Extensions responseExtensions) { @@ -56,7 +56,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp public ResponseData( ResponderID responderID, - DerGeneralizedTime producedAt, + Asn1GeneralizedTime producedAt, Asn1Sequence responses, X509Extensions responseExtensions) : this(V1, responderID, producedAt, responses, responseExtensions) @@ -90,7 +90,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp } this.responderID = ResponderID.GetInstance(seq[index++]); - this.producedAt = (DerGeneralizedTime)seq[index++]; + this.producedAt = (Asn1GeneralizedTime)seq[index++]; this.responses = (Asn1Sequence)seq[index++]; if (seq.Count > index) @@ -110,7 +110,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp get { return responderID; } } - public DerGeneralizedTime ProducedAt + public Asn1GeneralizedTime ProducedAt { get { return producedAt; } } diff --git a/crypto/src/asn1/ocsp/RevokedInfo.cs b/crypto/src/asn1/ocsp/RevokedInfo.cs index c67be0678..e6438dd08 100644 --- a/crypto/src/asn1/ocsp/RevokedInfo.cs +++ b/crypto/src/asn1/ocsp/RevokedInfo.cs @@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp public class RevokedInfo : Asn1Encodable { - private readonly DerGeneralizedTime revocationTime; + private readonly Asn1GeneralizedTime revocationTime; private readonly CrlReason revocationReason; public static RevokedInfo GetInstance( @@ -35,13 +35,13 @@ namespace Org.BouncyCastle.Asn1.Ocsp } public RevokedInfo( - DerGeneralizedTime revocationTime) + Asn1GeneralizedTime revocationTime) : this(revocationTime, null) { } public RevokedInfo( - DerGeneralizedTime revocationTime, + Asn1GeneralizedTime revocationTime, CrlReason revocationReason) { if (revocationTime == null) @@ -54,7 +54,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp private RevokedInfo( Asn1Sequence seq) { - this.revocationTime = (DerGeneralizedTime) seq[0]; + this.revocationTime = (Asn1GeneralizedTime)seq[0]; if (seq.Count > 1) { @@ -63,7 +63,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp } } - public DerGeneralizedTime RevocationTime + public Asn1GeneralizedTime RevocationTime { get { return revocationTime; } } diff --git a/crypto/src/asn1/ocsp/SingleResponse.cs b/crypto/src/asn1/ocsp/SingleResponse.cs index ecdf3dab0..42b451af7 100644 --- a/crypto/src/asn1/ocsp/SingleResponse.cs +++ b/crypto/src/asn1/ocsp/SingleResponse.cs @@ -10,15 +10,15 @@ namespace Org.BouncyCastle.Asn1.Ocsp { private readonly CertID certID; private readonly CertStatus certStatus; - private readonly DerGeneralizedTime thisUpdate; - private readonly DerGeneralizedTime nextUpdate; + private readonly Asn1GeneralizedTime thisUpdate; + private readonly Asn1GeneralizedTime nextUpdate; private readonly X509Extensions singleExtensions; public SingleResponse( CertID certID, CertStatus certStatus, - DerGeneralizedTime thisUpdate, - DerGeneralizedTime nextUpdate, + Asn1GeneralizedTime thisUpdate, + Asn1GeneralizedTime nextUpdate, X509Extensions singleExtensions) { this.certID = certID; @@ -33,11 +33,11 @@ namespace Org.BouncyCastle.Asn1.Ocsp { this.certID = CertID.GetInstance(seq[0]); this.certStatus = CertStatus.GetInstance(seq[1]); - this.thisUpdate = (DerGeneralizedTime)seq[2]; + this.thisUpdate = (Asn1GeneralizedTime)seq[2]; if (seq.Count > 4) { - this.nextUpdate = DerGeneralizedTime.GetInstance( + this.nextUpdate = Asn1GeneralizedTime.GetInstance( (Asn1TaggedObject) seq[3], true); this.singleExtensions = X509Extensions.GetInstance( (Asn1TaggedObject) seq[4], true); @@ -48,7 +48,7 @@ namespace Org.BouncyCastle.Asn1.Ocsp if (o.TagNo == 0) { - this.nextUpdate = DerGeneralizedTime.GetInstance(o, true); + this.nextUpdate = Asn1GeneralizedTime.GetInstance(o, true); } else { @@ -90,12 +90,12 @@ namespace Org.BouncyCastle.Asn1.Ocsp get { return certStatus; } } - public DerGeneralizedTime ThisUpdate + public Asn1GeneralizedTime ThisUpdate { get { return thisUpdate; } } - public DerGeneralizedTime NextUpdate + public Asn1GeneralizedTime NextUpdate { get { return nextUpdate; } } diff --git a/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs b/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs index 1a6a5417a..570e0ded7 100644 --- a/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs +++ b/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs @@ -138,11 +138,12 @@ namespace Org.BouncyCastle.Asn1.Pkcs public static readonly DerObjectIdentifier IdAlg = IdSmime.Branch("3"); - public static readonly DerObjectIdentifier IdAlgEsdh = IdAlg.Branch("5"); - public static readonly DerObjectIdentifier IdAlgCms3DesWrap = IdAlg.Branch("6"); - public static readonly DerObjectIdentifier IdAlgCmsRC2Wrap = IdAlg.Branch("7"); - public static readonly DerObjectIdentifier IdAlgPwriKek = IdAlg.Branch("9"); - public static readonly DerObjectIdentifier IdAlgSsdh = IdAlg.Branch("10"); + public static readonly DerObjectIdentifier IdAlgEsdh = IdAlg.Branch("5"); + public static readonly DerObjectIdentifier IdAlgCms3DesWrap = IdAlg.Branch("6"); + public static readonly DerObjectIdentifier IdAlgCmsRC2Wrap = IdAlg.Branch("7"); + public static readonly DerObjectIdentifier IdAlgZlibCompress = IdAlg.Branch("8"); + public static readonly DerObjectIdentifier IdAlgPwriKek = IdAlg.Branch("9"); + public static readonly DerObjectIdentifier IdAlgSsdh = IdAlg.Branch("10"); /* * <pre> diff --git a/crypto/src/asn1/sec/ECPrivateKeyStructure.cs b/crypto/src/asn1/sec/ECPrivateKeyStructure.cs index 769ab2970..89b87bf2b 100644 --- a/crypto/src/asn1/sec/ECPrivateKeyStructure.cs +++ b/crypto/src/asn1/sec/ECPrivateKeyStructure.cs @@ -1,6 +1,5 @@ using System; -using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Math; using Org.BouncyCastle.Utilities; @@ -12,23 +11,20 @@ namespace Org.BouncyCastle.Asn1.Sec public class ECPrivateKeyStructure : Asn1Encodable { - private readonly Asn1Sequence seq; + private readonly Asn1Sequence m_seq; public static ECPrivateKeyStructure GetInstance(object obj) { if (obj == null) return null; - if (obj is ECPrivateKeyStructure) - return (ECPrivateKeyStructure)obj; + if (obj is ECPrivateKeyStructure ecPrivateKeyStructure) + return ecPrivateKeyStructure; return new ECPrivateKeyStructure(Asn1Sequence.GetInstance(obj)); } private ECPrivateKeyStructure(Asn1Sequence seq) { - if (seq == null) - throw new ArgumentNullException("seq"); - - this.seq = seq; + m_seq = seq ?? throw new ArgumentNullException(nameof(seq)); } public ECPrivateKeyStructure( @@ -53,9 +49,9 @@ namespace Org.BouncyCastle.Asn1.Sec Asn1Encodable parameters) { if (key == null) - throw new ArgumentNullException("key"); + throw new ArgumentNullException(nameof(key)); if (orderBitLength < key.BitLength) - throw new ArgumentException("must be >= key bitlength", "orderBitLength"); + throw new ArgumentException("must be >= key bitlength", nameof(orderBitLength)); byte[] bytes = BigIntegers.AsUnsignedByteArray((orderBitLength + 7) / 8, key); @@ -63,48 +59,42 @@ namespace Org.BouncyCastle.Asn1.Sec new DerInteger(1), new DerOctetString(bytes)); - if (parameters != null) - { - v.Add(new DerTaggedObject(true, 0, parameters)); - } - - if (publicKey != null) - { - v.Add(new DerTaggedObject(true, 1, publicKey)); - } + v.AddOptionalTagged(true, 0, parameters); + v.AddOptionalTagged(true, 1, publicKey); - this.seq = new DerSequence(v); + m_seq = new DerSequence(v); } public virtual BigInteger GetKey() { - Asn1OctetString octs = (Asn1OctetString) seq[1]; + Asn1OctetString octs = (Asn1OctetString)m_seq[1]; return new BigInteger(1, octs.GetOctets()); } public virtual DerBitString GetPublicKey() { - return (DerBitString) GetObjectInTag(1); + return (DerBitString)GetObjectInTag(1, Asn1Tags.BitString); } public virtual Asn1Object GetParameters() { - return GetObjectInTag(0); + return GetObjectInTag(0, -1); } - private Asn1Object GetObjectInTag(int tagNo) + private Asn1Object GetObjectInTag(int tagNo, int baseTagNo) { - foreach (Asn1Encodable ae in seq) + foreach (Asn1Encodable ae in m_seq) { Asn1Object obj = ae.ToAsn1Object(); - if (obj is Asn1TaggedObject) + if (obj is Asn1TaggedObject tag) { - Asn1TaggedObject tag = (Asn1TaggedObject) obj; - if (tag.TagNo == tagNo) + if (tag.HasContextTag(tagNo)) { - return tag.GetObject(); + return baseTagNo < 0 + ? tag.GetExplicitBaseObject().ToAsn1Object() + : tag.GetBaseUniversal(true, baseTagNo); } } } @@ -121,7 +111,7 @@ namespace Org.BouncyCastle.Asn1.Sec */ public override Asn1Object ToAsn1Object() { - return seq; + return m_seq; } } } diff --git a/crypto/src/asn1/tsp/TSTInfo.cs b/crypto/src/asn1/tsp/TSTInfo.cs index 28a840e77..dde11494c 100644 --- a/crypto/src/asn1/tsp/TSTInfo.cs +++ b/crypto/src/asn1/tsp/TSTInfo.cs @@ -11,7 +11,7 @@ namespace Org.BouncyCastle.Asn1.Tsp private readonly DerObjectIdentifier tsaPolicyId; private readonly MessageImprint messageImprint; private readonly DerInteger serialNumber; - private readonly DerGeneralizedTime genTime; + private readonly Asn1GeneralizedTime genTime; private readonly Accuracy accuracy; private readonly DerBoolean ordering; private readonly DerInteger nonce; @@ -49,7 +49,7 @@ namespace Org.BouncyCastle.Asn1.Tsp // genTime e.MoveNext(); - genTime = DerGeneralizedTime.GetInstance(e.Current); + genTime = Asn1GeneralizedTime.GetInstance(e.Current); // default for ordering ordering = DerBoolean.False; @@ -96,7 +96,7 @@ namespace Org.BouncyCastle.Asn1.Tsp DerObjectIdentifier tsaPolicyId, MessageImprint messageImprint, DerInteger serialNumber, - DerGeneralizedTime genTime, + Asn1GeneralizedTime genTime, Accuracy accuracy, DerBoolean ordering, DerInteger nonce, @@ -140,7 +140,7 @@ namespace Org.BouncyCastle.Asn1.Tsp get { return accuracy; } } - public DerGeneralizedTime GenTime + public Asn1GeneralizedTime GenTime { get { return genTime; } } diff --git a/crypto/src/asn1/util/Asn1Dump.cs b/crypto/src/asn1/util/Asn1Dump.cs index 7bae766c3..6c005f512 100644 --- a/crypto/src/asn1/util/Asn1Dump.cs +++ b/crypto/src/asn1/util/Asn1Dump.cs @@ -206,12 +206,12 @@ namespace Org.BouncyCastle.Asn1.Utilities buf.Append(indent); buf.AppendLine("VideotexString(" + videotexString.GetString() + ")"); } - else if (obj is DerUtcTime utcTime) + else if (obj is Asn1UtcTime utcTime) { buf.Append(indent); buf.AppendLine("UTCTime(" + utcTime.TimeString + ")"); } - else if (obj is DerGeneralizedTime generalizedTime) + else if (obj is Asn1GeneralizedTime generalizedTime) { buf.Append(indent); buf.AppendLine("GeneralizedTime(" + generalizedTime.GetTime() + ")"); diff --git a/crypto/src/asn1/x509/AttCertValidityPeriod.cs b/crypto/src/asn1/x509/AttCertValidityPeriod.cs index d31e07402..893bc0838 100644 --- a/crypto/src/asn1/x509/AttCertValidityPeriod.cs +++ b/crypto/src/asn1/x509/AttCertValidityPeriod.cs @@ -7,8 +7,8 @@ namespace Org.BouncyCastle.Asn1.X509 public class AttCertValidityPeriod : Asn1Encodable { - private readonly DerGeneralizedTime notBeforeTime; - private readonly DerGeneralizedTime notAfterTime; + private readonly Asn1GeneralizedTime notBeforeTime; + private readonly Asn1GeneralizedTime notAfterTime; public static AttCertValidityPeriod GetInstance( object obj) @@ -39,24 +39,24 @@ namespace Org.BouncyCastle.Asn1.X509 if (seq.Count != 2) throw new ArgumentException("Bad sequence size: " + seq.Count); - notBeforeTime = DerGeneralizedTime.GetInstance(seq[0]); - notAfterTime = DerGeneralizedTime.GetInstance(seq[1]); + notBeforeTime = Asn1GeneralizedTime.GetInstance(seq[0]); + notAfterTime = Asn1GeneralizedTime.GetInstance(seq[1]); } public AttCertValidityPeriod( - DerGeneralizedTime notBeforeTime, - DerGeneralizedTime notAfterTime) + Asn1GeneralizedTime notBeforeTime, + Asn1GeneralizedTime notAfterTime) { this.notBeforeTime = notBeforeTime; this.notAfterTime = notAfterTime; } - public DerGeneralizedTime NotBeforeTime + public Asn1GeneralizedTime NotBeforeTime { get { return notBeforeTime; } } - public DerGeneralizedTime NotAfterTime + public Asn1GeneralizedTime NotAfterTime { get { return notAfterTime; } } diff --git a/crypto/src/asn1/x509/PrivateKeyUsagePeriod.cs b/crypto/src/asn1/x509/PrivateKeyUsagePeriod.cs index 89e8de6cb..a87c2ee9e 100644 --- a/crypto/src/asn1/x509/PrivateKeyUsagePeriod.cs +++ b/crypto/src/asn1/x509/PrivateKeyUsagePeriod.cs @@ -36,7 +36,7 @@ namespace Org.BouncyCastle.Asn1.X509 throw new ArgumentException("unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } - private DerGeneralizedTime _notBefore, _notAfter; + private Asn1GeneralizedTime _notBefore, _notAfter; private PrivateKeyUsagePeriod( Asn1Sequence seq) @@ -45,21 +45,21 @@ namespace Org.BouncyCastle.Asn1.X509 { if (tObj.TagNo == 0) { - _notBefore = DerGeneralizedTime.GetInstance(tObj, false); + _notBefore = Asn1GeneralizedTime.GetInstance(tObj, false); } else if (tObj.TagNo == 1) { - _notAfter = DerGeneralizedTime.GetInstance(tObj, false); + _notAfter = Asn1GeneralizedTime.GetInstance(tObj, false); } } } - public DerGeneralizedTime NotBefore + public Asn1GeneralizedTime NotBefore { get { return _notBefore; } } - public DerGeneralizedTime NotAfter + public Asn1GeneralizedTime NotAfter { get { return _notAfter; } } diff --git a/crypto/src/asn1/x509/TBSCertList.cs b/crypto/src/asn1/x509/TBSCertList.cs index ab847d563..2b288850f 100644 --- a/crypto/src/asn1/x509/TBSCertList.cs +++ b/crypto/src/asn1/x509/TBSCertList.cs @@ -193,8 +193,8 @@ namespace Org.BouncyCastle.Asn1.X509 thisUpdate = Time.GetInstance(seq[seqPos++]); if (seqPos < seq.Count - && (seq[seqPos] is DerUtcTime - || seq[seqPos] is DerGeneralizedTime + && (seq[seqPos] is Asn1UtcTime + || seq[seqPos] is Asn1GeneralizedTime || seq[seqPos] is Time)) { nextUpdate = Time.GetInstance(seq[seqPos++]); diff --git a/crypto/src/asn1/x509/Time.cs b/crypto/src/asn1/x509/Time.cs index 26c972904..8260043aa 100644 --- a/crypto/src/asn1/x509/Time.cs +++ b/crypto/src/asn1/x509/Time.cs @@ -22,7 +22,7 @@ namespace Org.BouncyCastle.Asn1.X509 { if (time == null) throw new ArgumentNullException("time"); - if (!(time is DerUtcTime) && !(time is DerGeneralizedTime)) + if (!(time is Asn1UtcTime) && !(time is Asn1GeneralizedTime)) throw new ArgumentException("unknown object passed to Time"); this.time = time; @@ -47,27 +47,26 @@ namespace Org.BouncyCastle.Asn1.X509 } } - public static Time GetInstance( - object obj) + public static Time GetInstance(object obj) { - if (obj == null || obj is Time) - return (Time)obj; - if (obj is DerUtcTime) - return new Time((DerUtcTime)obj); - if (obj is DerGeneralizedTime) - return new Time((DerGeneralizedTime)obj); + if (obj == null) + return null; + if (obj is Time time) + return time; + if (obj is Asn1UtcTime utcTime) + return new Time(utcTime); + if (obj is Asn1GeneralizedTime generalizedTime) + return new Time(generalizedTime); throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj"); } public string GetTime() { - if (time is DerUtcTime) - { - return ((DerUtcTime) time).AdjustedTimeString; - } + if (time is Asn1UtcTime utcTime) + return utcTime.AdjustedTimeString; - return ((DerGeneralizedTime) time).GetTime(); + return ((Asn1GeneralizedTime)time).GetTime(); } /// <summary> @@ -78,14 +77,10 @@ namespace Org.BouncyCastle.Asn1.X509 { try { - if (time is DerUtcTime) - { - return ((DerUtcTime)time).ToAdjustedDateTime(); - } - else - { - return ((DerGeneralizedTime)time).ToDateTime(); - } + if (time is Asn1UtcTime utcTime) + return utcTime.ToAdjustedDateTime(); + + return ((Asn1GeneralizedTime)time).ToDateTime(); } catch (FormatException e) { diff --git a/crypto/src/asn1/x509/V1TBSCertificateGenerator.cs b/crypto/src/asn1/x509/V1TBSCertificateGenerator.cs index 20b525a48..9cbff1ef0 100644 --- a/crypto/src/asn1/x509/V1TBSCertificateGenerator.cs +++ b/crypto/src/asn1/x509/V1TBSCertificateGenerator.cs @@ -56,7 +56,7 @@ namespace Org.BouncyCastle.Asn1.X509 } public void SetStartDate( - DerUtcTime startDate) + Asn1UtcTime startDate) { this.startDate = new Time(startDate); } @@ -68,7 +68,7 @@ namespace Org.BouncyCastle.Asn1.X509 } public void SetEndDate( - DerUtcTime endDate) + Asn1UtcTime endDate) { this.endDate = new Time(endDate); } diff --git a/crypto/src/asn1/x509/V2AttributeCertificateInfoGenerator.cs b/crypto/src/asn1/x509/V2AttributeCertificateInfoGenerator.cs index 02580b5b8..c78c966b0 100644 --- a/crypto/src/asn1/x509/V2AttributeCertificateInfoGenerator.cs +++ b/crypto/src/asn1/x509/V2AttributeCertificateInfoGenerator.cs @@ -26,11 +26,13 @@ namespace Org.BouncyCastle.Asn1.X509 internal AttCertIssuer issuer; internal AlgorithmIdentifier signature; internal DerInteger serialNumber; -// internal AttCertValidityPeriod attrCertValidityPeriod; internal Asn1EncodableVector attributes; internal DerBitString issuerUniqueID; internal X509Extensions extensions; - internal DerGeneralizedTime startDate, endDate; + + // Note: validity period start/end dates stored directly + //internal AttCertValidityPeriod attrCertValidityPeriod; + internal Asn1GeneralizedTime startDate, endDate; public V2AttributeCertificateInfoGenerator() { @@ -78,13 +80,13 @@ namespace Org.BouncyCastle.Asn1.X509 } public void SetStartDate( - DerGeneralizedTime startDate) + Asn1GeneralizedTime startDate) { this.startDate = startDate; } public void SetEndDate( - DerGeneralizedTime endDate) + Asn1GeneralizedTime endDate) { this.endDate = endDate; } diff --git a/crypto/src/asn1/x509/V2TBSCertListGenerator.cs b/crypto/src/asn1/x509/V2TBSCertListGenerator.cs index 1d58751fd..aa1a0b95d 100644 --- a/crypto/src/asn1/x509/V2TBSCertListGenerator.cs +++ b/crypto/src/asn1/x509/V2TBSCertListGenerator.cs @@ -55,13 +55,13 @@ namespace Org.BouncyCastle.Asn1.X509 } public void SetThisUpdate( - DerUtcTime thisUpdate) + Asn1UtcTime thisUpdate) { this.thisUpdate = new Time(thisUpdate); } public void SetNextUpdate( - DerUtcTime nextUpdate) + Asn1UtcTime nextUpdate) { this.nextUpdate = (nextUpdate != null) ? new Time(nextUpdate) @@ -90,7 +90,7 @@ namespace Org.BouncyCastle.Asn1.X509 crlEntries.Add(crlEntry); } - public void AddCrlEntry(DerInteger userCertificate, DerUtcTime revocationDate, int reason) + public void AddCrlEntry(DerInteger userCertificate, Asn1UtcTime revocationDate, int reason) { AddCrlEntry(userCertificate, new Time(revocationDate), reason); } @@ -101,7 +101,7 @@ namespace Org.BouncyCastle.Asn1.X509 } public void AddCrlEntry(DerInteger userCertificate, Time revocationDate, int reason, - DerGeneralizedTime invalidityDate) + Asn1GeneralizedTime invalidityDate) { var extOids = new List<DerObjectIdentifier>(); var extValues = new List<X509Extension>(); diff --git a/crypto/src/asn1/x509/V3TBSCertificateGenerator.cs b/crypto/src/asn1/x509/V3TBSCertificateGenerator.cs index beb469a0d..544582ddb 100644 --- a/crypto/src/asn1/x509/V3TBSCertificateGenerator.cs +++ b/crypto/src/asn1/x509/V3TBSCertificateGenerator.cs @@ -58,7 +58,7 @@ namespace Org.BouncyCastle.Asn1.X509 } public void SetStartDate( - DerUtcTime startDate) + Asn1UtcTime startDate) { this.startDate = new Time(startDate); } @@ -70,7 +70,7 @@ namespace Org.BouncyCastle.Asn1.X509 } public void SetEndDate( - DerUtcTime endDate) + Asn1UtcTime endDate) { this.endDate = new Time(endDate); } diff --git a/crypto/src/asn1/x509/X509DefaultEntryConverter.cs b/crypto/src/asn1/x509/X509DefaultEntryConverter.cs index 7282ead26..d155efc5a 100644 --- a/crypto/src/asn1/x509/X509DefaultEntryConverter.cs +++ b/crypto/src/asn1/x509/X509DefaultEntryConverter.cs @@ -46,7 +46,7 @@ namespace Org.BouncyCastle.Asn1.X509 if (oid.Equals(X509Name.DateOfBirth)) // accept time string as well as # (for compatibility) { - return new DerGeneralizedTime(value); + return new Asn1GeneralizedTime(value); } if (oid.Equals(X509Name.C) diff --git a/crypto/src/asn1/x509/sigi/PersonalData.cs b/crypto/src/asn1/x509/sigi/PersonalData.cs index 439039888..e8c75bf93 100644 --- a/crypto/src/asn1/x509/sigi/PersonalData.cs +++ b/crypto/src/asn1/x509/sigi/PersonalData.cs @@ -29,7 +29,7 @@ namespace Org.BouncyCastle.Asn1.X509.SigI { private readonly NameOrPseudonym nameOrPseudonym; private readonly BigInteger nameDistinguisher; - private readonly DerGeneralizedTime dateOfBirth; + private readonly Asn1GeneralizedTime dateOfBirth; private readonly DirectoryString placeOfBirth; private readonly string gender; private readonly DirectoryString postalAddress; @@ -88,7 +88,7 @@ namespace Org.BouncyCastle.Asn1.X509.SigI nameDistinguisher = DerInteger.GetInstance(o, false).Value; break; case 1: - dateOfBirth = DerGeneralizedTime.GetInstance(o, false); + dateOfBirth = Asn1GeneralizedTime.GetInstance(o, false); break; case 2: placeOfBirth = DirectoryString.GetInstance(o, true); @@ -118,7 +118,7 @@ namespace Org.BouncyCastle.Asn1.X509.SigI public PersonalData( NameOrPseudonym nameOrPseudonym, BigInteger nameDistinguisher, - DerGeneralizedTime dateOfBirth, + Asn1GeneralizedTime dateOfBirth, DirectoryString placeOfBirth, string gender, DirectoryString postalAddress) @@ -141,7 +141,7 @@ namespace Org.BouncyCastle.Asn1.X509.SigI get { return nameDistinguisher; } } - public DerGeneralizedTime DateOfBirth + public Asn1GeneralizedTime DateOfBirth { get { return dateOfBirth; } } |