Decompiled source of System Formats Asn1 v8.0.100
BepInEx/core/System.Formats.Asn1/netstandard2.0/System.Formats.Asn1.dll
Decompiled 4 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Buffers; using System.Buffers.Binary; using System.Buffers.Text; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Numerics; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using FxResources.System.Formats.Asn1; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: AssemblyMetadata("PreferInbox", "True")] [assembly: AssemblyDefaultAlias("System.Formats.Asn1")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: CLSCompliant(true)] [assembly: AssemblyMetadata("IsTrimmable", "True")] [assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)] [assembly: AssemblyCompany("Microsoft Corporation")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyDescription("Provides classes that can read and write the ASN.1 BER, CER, and DER data formats.\r\n\r\nCommonly Used Types:\r\nSystem.Formats.Asn1.AsnReader\r\nSystem.Formats.Asn1.AsnWriter")] [assembly: AssemblyFileVersion("8.0.724.31311")] [assembly: AssemblyInformationalVersion("8.0.7+2aade6beb02ea367fd97c4070a4198802fe61c03")] [assembly: AssemblyProduct("Microsoft® .NET")] [assembly: AssemblyTitle("System.Formats.Asn1")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dotnet/runtime")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("8.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: System.Runtime.CompilerServices.NullablePublicOnly(false)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class NullablePublicOnlyAttribute : Attribute { public readonly bool IncludesInternals; public NullablePublicOnlyAttribute(bool P_0) { IncludesInternals = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace FxResources.System.Formats.Asn1 { internal static class SR { } } namespace System { internal static class LocalAppContextSwitches { private static int s_allowAnySizeOid; public static bool AllowAnySizeOid { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return GetCachedSwitchValue("System.Formats.Asn1.AllowAnySizeOid", ref s_allowAnySizeOid); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool GetSwitchValue(string switchName, ref bool switchValue) { return AppContext.TryGetSwitch(switchName, out switchValue); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool GetCachedSwitchValue(string switchName, ref int cachedSwitchValue) { if (cachedSwitchValue < 0) { return false; } if (cachedSwitchValue > 0) { return true; } return GetCachedSwitchValueInternal(switchName, ref cachedSwitchValue); } private static bool GetCachedSwitchValueInternal(string switchName, ref int cachedSwitchValue) { if (!AppContext.TryGetSwitch(switchName, out var isEnabled)) { isEnabled = GetSwitchDefaultValue(switchName); } AppContext.TryGetSwitch("TestSwitch.LocalAppContext.DisableCaching", out var isEnabled2); if (!isEnabled2) { cachedSwitchValue = (isEnabled ? 1 : (-1)); } return isEnabled; } private static bool GetSwitchDefaultValue(string switchName) { return switchName switch { "Switch.System.Runtime.Serialization.SerializationGuard" => true, "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization" => true, "System.Xml.XmlResolver.IsNetworkingEnabledByDefault" => true, _ => false, }; } } internal static class Obsoletions { internal const string SharedUrlFormat = "https://aka.ms/dotnet-warnings/{0}"; internal const string SystemTextEncodingUTF7Message = "The UTF-7 encoding is insecure and should not be used. Consider using UTF-8 instead."; internal const string SystemTextEncodingUTF7DiagId = "SYSLIB0001"; internal const string PrincipalPermissionAttributeMessage = "PrincipalPermissionAttribute is not honored by the runtime and must not be used."; internal const string PrincipalPermissionAttributeDiagId = "SYSLIB0002"; internal const string CodeAccessSecurityMessage = "Code Access Security is not supported or honored by the runtime."; internal const string CodeAccessSecurityDiagId = "SYSLIB0003"; internal const string ConstrainedExecutionRegionMessage = "The Constrained Execution Region (CER) feature is not supported."; internal const string ConstrainedExecutionRegionDiagId = "SYSLIB0004"; internal const string GlobalAssemblyCacheMessage = "The Global Assembly Cache is not supported."; internal const string GlobalAssemblyCacheDiagId = "SYSLIB0005"; internal const string ThreadAbortMessage = "Thread.Abort is not supported and throws PlatformNotSupportedException."; internal const string ThreadResetAbortMessage = "Thread.ResetAbort is not supported and throws PlatformNotSupportedException."; internal const string ThreadAbortDiagId = "SYSLIB0006"; internal const string DefaultCryptoAlgorithmsMessage = "The default implementation of this cryptography algorithm is not supported."; internal const string DefaultCryptoAlgorithmsDiagId = "SYSLIB0007"; internal const string CreatePdbGeneratorMessage = "The CreatePdbGenerator API is not supported and throws PlatformNotSupportedException."; internal const string CreatePdbGeneratorDiagId = "SYSLIB0008"; internal const string AuthenticationManagerMessage = "The AuthenticationManager Authenticate and PreAuthenticate methods are not supported and throw PlatformNotSupportedException."; internal const string AuthenticationManagerDiagId = "SYSLIB0009"; internal const string RemotingApisMessage = "This Remoting API is not supported and throws PlatformNotSupportedException."; internal const string RemotingApisDiagId = "SYSLIB0010"; internal const string BinaryFormatterMessage = "BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information."; internal const string BinaryFormatterDiagId = "SYSLIB0011"; internal const string CodeBaseMessage = "Assembly.CodeBase and Assembly.EscapedCodeBase are only included for .NET Framework compatibility. Use Assembly.Location instead."; internal const string CodeBaseDiagId = "SYSLIB0012"; internal const string EscapeUriStringMessage = "Uri.EscapeUriString can corrupt the Uri string in some cases. Consider using Uri.EscapeDataString for query string components instead."; internal const string EscapeUriStringDiagId = "SYSLIB0013"; internal const string WebRequestMessage = "WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead."; internal const string WebRequestDiagId = "SYSLIB0014"; internal const string DisablePrivateReflectionAttributeMessage = "DisablePrivateReflectionAttribute has no effect in .NET 6.0+."; internal const string DisablePrivateReflectionAttributeDiagId = "SYSLIB0015"; internal const string GetContextInfoMessage = "Use the Graphics.GetContextInfo overloads that accept arguments for better performance and fewer allocations."; internal const string GetContextInfoDiagId = "SYSLIB0016"; internal const string StrongNameKeyPairMessage = "Strong name signing is not supported and throws PlatformNotSupportedException."; internal const string StrongNameKeyPairDiagId = "SYSLIB0017"; internal const string ReflectionOnlyLoadingMessage = "ReflectionOnly loading is not supported and throws PlatformNotSupportedException."; internal const string ReflectionOnlyLoadingDiagId = "SYSLIB0018"; internal const string RuntimeEnvironmentMessage = "RuntimeEnvironment members SystemConfigurationFile, GetRuntimeInterfaceAsIntPtr, and GetRuntimeInterfaceAsObject are not supported and throw PlatformNotSupportedException."; internal const string RuntimeEnvironmentDiagId = "SYSLIB0019"; internal const string JsonSerializerOptionsIgnoreNullValuesMessage = "JsonSerializerOptions.IgnoreNullValues is obsolete. To ignore null values when serializing, set DefaultIgnoreCondition to JsonIgnoreCondition.WhenWritingNull."; internal const string JsonSerializerOptionsIgnoreNullValuesDiagId = "SYSLIB0020"; internal const string DerivedCryptographicTypesMessage = "Derived cryptographic types are obsolete. Use the Create method on the base type instead."; internal const string DerivedCryptographicTypesDiagId = "SYSLIB0021"; internal const string RijndaelMessage = "The Rijndael and RijndaelManaged types are obsolete. Use Aes instead."; internal const string RijndaelDiagId = "SYSLIB0022"; internal const string RNGCryptoServiceProviderMessage = "RNGCryptoServiceProvider is obsolete. To generate a random number, use one of the RandomNumberGenerator static methods instead."; internal const string RNGCryptoServiceProviderDiagId = "SYSLIB0023"; internal const string AppDomainCreateUnloadMessage = "Creating and unloading AppDomains is not supported and throws an exception."; internal const string AppDomainCreateUnloadDiagId = "SYSLIB0024"; internal const string SuppressIldasmAttributeMessage = "SuppressIldasmAttribute has no effect in .NET 6.0+."; internal const string SuppressIldasmAttributeDiagId = "SYSLIB0025"; internal const string X509CertificateImmutableMessage = "X509Certificate and X509Certificate2 are immutable. Use the appropriate constructor to create a new certificate."; internal const string X509CertificateImmutableDiagId = "SYSLIB0026"; internal const string PublicKeyPropertyMessage = "PublicKey.Key is obsolete. Use the appropriate method to get the public key, such as GetRSAPublicKey."; internal const string PublicKeyPropertyDiagId = "SYSLIB0027"; internal const string X509CertificatePrivateKeyMessage = "X509Certificate2.PrivateKey is obsolete. Use the appropriate method to get the private key, such as GetRSAPrivateKey, or use the CopyWithPrivateKey method to create a new instance with a private key."; internal const string X509CertificatePrivateKeyDiagId = "SYSLIB0028"; internal const string ProduceLegacyHmacValuesMessage = "ProduceLegacyHmacValues is obsolete. Producing legacy HMAC values is not supported."; internal const string ProduceLegacyHmacValuesDiagId = "SYSLIB0029"; internal const string UseManagedSha1Message = "HMACSHA1 always uses the algorithm implementation provided by the platform. Use a constructor without the useManagedSha1 parameter."; internal const string UseManagedSha1DiagId = "SYSLIB0030"; internal const string CryptoConfigEncodeOIDMessage = "EncodeOID is obsolete. Use the ASN.1 functionality provided in System.Formats.Asn1."; internal const string CryptoConfigEncodeOIDDiagId = "SYSLIB0031"; internal const string CorruptedStateRecoveryMessage = "Recovery from corrupted process state exceptions is not supported; HandleProcessCorruptedStateExceptionsAttribute is ignored."; internal const string CorruptedStateRecoveryDiagId = "SYSLIB0032"; internal const string Rfc2898CryptDeriveKeyMessage = "Rfc2898DeriveBytes.CryptDeriveKey is obsolete and is not supported. Use PasswordDeriveBytes.CryptDeriveKey instead."; internal const string Rfc2898CryptDeriveKeyDiagId = "SYSLIB0033"; internal const string CmsSignerCspParamsCtorMessage = "CmsSigner(CspParameters) is obsolete and is not supported. Use an alternative constructor instead."; internal const string CmsSignerCspParamsCtorDiagId = "SYSLIB0034"; internal const string SignerInfoCounterSigMessage = "ComputeCounterSignature without specifying a CmsSigner is obsolete and is not supported. Use the overload that accepts a CmsSigner."; internal const string SignerInfoCounterSigDiagId = "SYSLIB0035"; internal const string RegexCompileToAssemblyMessage = "Regex.CompileToAssembly is obsolete and not supported. Use the GeneratedRegexAttribute with the regular expression source generator instead."; internal const string RegexCompileToAssemblyDiagId = "SYSLIB0036"; internal const string AssemblyNameMembersMessage = "AssemblyName members HashAlgorithm, ProcessorArchitecture, and VersionCompatibility are obsolete and not supported."; internal const string AssemblyNameMembersDiagId = "SYSLIB0037"; internal const string SystemDataSerializationFormatBinaryMessage = "SerializationFormat.Binary is obsolete and should not be used. See https://aka.ms/serializationformat-binary-obsolete for more information."; internal const string SystemDataSerializationFormatBinaryDiagId = "SYSLIB0038"; internal const string TlsVersion10and11Message = "TLS versions 1.0 and 1.1 have known vulnerabilities and are not recommended. Use a newer TLS version instead, or use SslProtocols.None to defer to OS defaults."; internal const string TlsVersion10and11DiagId = "SYSLIB0039"; internal const string EncryptionPolicyMessage = "EncryptionPolicy.NoEncryption and AllowEncryption significantly reduce security and should not be used in production code."; internal const string EncryptionPolicyDiagId = "SYSLIB0040"; internal const string Rfc2898OutdatedCtorMessage = "The default hash algorithm and iteration counts in Rfc2898DeriveBytes constructors are outdated and insecure. Use a constructor that accepts the hash algorithm and the number of iterations."; internal const string Rfc2898OutdatedCtorDiagId = "SYSLIB0041"; internal const string EccXmlExportImportMessage = "ToXmlString and FromXmlString have no implementation for ECC types, and are obsolete. Use a standard import and export format such as ExportSubjectPublicKeyInfo or ImportSubjectPublicKeyInfo for public keys and ExportPkcs8PrivateKey or ImportPkcs8PrivateKey for private keys."; internal const string EccXmlExportImportDiagId = "SYSLIB0042"; internal const string EcDhPublicKeyBlobMessage = "ECDiffieHellmanPublicKey.ToByteArray() and the associated constructor do not have a consistent and interoperable implementation on all platforms. Use ECDiffieHellmanPublicKey.ExportSubjectPublicKeyInfo() instead."; internal const string EcDhPublicKeyBlobDiagId = "SYSLIB0043"; internal const string AssemblyNameCodeBaseMessage = "AssemblyName.CodeBase and AssemblyName.EscapedCodeBase are obsolete. Using them for loading an assembly is not supported."; internal const string AssemblyNameCodeBaseDiagId = "SYSLIB0044"; internal const string CryptoStringFactoryMessage = "Cryptographic factory methods accepting an algorithm name are obsolete. Use the parameterless Create factory method on the algorithm type instead."; internal const string CryptoStringFactoryDiagId = "SYSLIB0045"; internal const string ControlledExecutionRunMessage = "ControlledExecution.Run method may corrupt the process and should not be used in production code."; internal const string ControlledExecutionRunDiagId = "SYSLIB0046"; internal const string XmlSecureResolverMessage = "XmlSecureResolver is obsolete. Use XmlResolver.ThrowingResolver instead when attempting to forbid XML external entity resolution."; internal const string XmlSecureResolverDiagId = "SYSLIB0047"; internal const string RsaEncryptDecryptValueMessage = "RSA.EncryptValue and DecryptValue are not supported and throw NotSupportedException. Use RSA.Encrypt and RSA.Decrypt instead."; internal const string RsaEncryptDecryptDiagId = "SYSLIB0048"; internal const string JsonSerializerOptionsAddContextMessage = "JsonSerializerOptions.AddContext is obsolete. To register a JsonSerializerContext, use either the TypeInfoResolver or TypeInfoResolverChain properties."; internal const string JsonSerializerOptionsAddContextDiagId = "SYSLIB0049"; internal const string LegacyFormatterMessage = "Formatter-based serialization is obsolete and should not be used."; internal const string LegacyFormatterDiagId = "SYSLIB0050"; internal const string LegacyFormatterImplMessage = "This API supports obsolete formatter-based serialization. It should not be called or extended by application code."; internal const string LegacyFormatterImplDiagId = "SYSLIB0051"; internal const string RegexExtensibilityImplMessage = "This API supports obsolete mechanisms for Regex extensibility. It is not supported."; internal const string RegexExtensibilityDiagId = "SYSLIB0052"; internal const string AesGcmTagConstructorMessage = "AesGcm should indicate the required tag size for encryption and decryption. Use a constructor that accepts the tag size."; internal const string AesGcmTagConstructorDiagId = "SYSLIB0053"; } internal static class SR { private static readonly bool s_usingResourceKeys = AppContext.TryGetSwitch("System.Resources.UseSystemResourceKeys", out var isEnabled) && isEnabled; private static ResourceManager s_resourceManager; internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(SR))); internal static string Argument_DestinationTooShort => GetResourceString("Argument_DestinationTooShort"); internal static string Argument_EnumeratedValueRequiresNonFlagsEnum => GetResourceString("Argument_EnumeratedValueRequiresNonFlagsEnum"); internal static string Argument_EnumeratedValueBackingTypeNotSupported => GetResourceString("Argument_EnumeratedValueBackingTypeNotSupported"); internal static string Argument_InvalidOidValue => GetResourceString("Argument_InvalidOidValue"); internal static string Argument_NamedBitListRequiresFlagsEnum => GetResourceString("Argument_NamedBitListRequiresFlagsEnum"); internal static string Argument_SourceOverlapsDestination => GetResourceString("Argument_SourceOverlapsDestination"); internal static string Argument_Tag_NotCharacterString => GetResourceString("Argument_Tag_NotCharacterString"); internal static string Argument_IntegerCannotBeEmpty => GetResourceString("Argument_IntegerCannotBeEmpty"); internal static string Argument_IntegerRedundantByte => GetResourceString("Argument_IntegerRedundantByte"); internal static string Argument_UniversalValueIsFixed => GetResourceString("Argument_UniversalValueIsFixed"); internal static string Argument_UnusedBitCountMustBeZero => GetResourceString("Argument_UnusedBitCountMustBeZero"); internal static string Argument_UnusedBitCountRange => GetResourceString("Argument_UnusedBitCountRange"); internal static string Argument_UnusedBitWasSet => GetResourceString("Argument_UnusedBitWasSet"); internal static string Argument_WriteEncodedValue_OneValueAtATime => GetResourceString("Argument_WriteEncodedValue_OneValueAtATime"); internal static string ArgumentOutOfRange_NeedNonNegNum => GetResourceString("ArgumentOutOfRange_NeedNonNegNum"); internal static string AsnWriter_EncodeUnbalancedStack => GetResourceString("AsnWriter_EncodeUnbalancedStack"); internal static string AsnWriter_PopWrongTag => GetResourceString("AsnWriter_PopWrongTag"); internal static string ContentException_CerRequiresIndefiniteLength => GetResourceString("ContentException_CerRequiresIndefiniteLength"); internal static string ContentException_ConstructedEncodingRequired => GetResourceString("ContentException_ConstructedEncodingRequired"); internal static string ContentException_DefaultMessage => GetResourceString("ContentException_DefaultMessage"); internal static string ContentException_EnumeratedValueTooBig => GetResourceString("ContentException_EnumeratedValueTooBig"); internal static string ContentException_InvalidUnderCer_TryBerOrDer => GetResourceString("ContentException_InvalidUnderCer_TryBerOrDer"); internal static string ContentException_InvalidUnderCerOrDer_TryBer => GetResourceString("ContentException_InvalidUnderCerOrDer_TryBer"); internal static string ContentException_InvalidUnderDer_TryBerOrCer => GetResourceString("ContentException_InvalidUnderDer_TryBerOrCer"); internal static string ContentException_InvalidTag => GetResourceString("ContentException_InvalidTag"); internal static string ContentException_LengthExceedsPayload => GetResourceString("ContentException_LengthExceedsPayload"); internal static string ContentException_LengthRuleSetConstraint => GetResourceString("ContentException_LengthRuleSetConstraint"); internal static string ContentException_LengthTooBig => GetResourceString("ContentException_LengthTooBig"); internal static string ContentException_NamedBitListValueTooBig => GetResourceString("ContentException_NamedBitListValueTooBig"); internal static string ContentException_OidTooBig => GetResourceString("ContentException_OidTooBig"); internal static string ContentException_PrimitiveEncodingRequired => GetResourceString("ContentException_PrimitiveEncodingRequired"); internal static string ContentException_SetOfNotSorted => GetResourceString("ContentException_SetOfNotSorted"); internal static string ContentException_TooMuchData => GetResourceString("ContentException_TooMuchData"); internal static string ContentException_WrongTag => GetResourceString("ContentException_WrongTag"); internal static bool UsingResourceKeys() { return s_usingResourceKeys; } private static string GetResourceString(string resourceKey) { if (UsingResourceKeys()) { return resourceKey; } string result = null; try { result = ResourceManager.GetString(resourceKey); } catch (MissingManifestResourceException) { } return result; } private static string GetResourceString(string resourceKey, string defaultString) { string resourceString = GetResourceString(resourceKey); if (!(resourceKey == resourceString) && resourceString != null) { return resourceString; } return defaultString; } internal static string Format(string resourceFormat, object p1) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1); } return string.Format(resourceFormat, p1); } internal static string Format(string resourceFormat, object p1, object p2) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2); } return string.Format(resourceFormat, p1, p2); } internal static string Format(string resourceFormat, object p1, object p2, object p3) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2, p3); } return string.Format(resourceFormat, p1, p2, p3); } internal static string Format(string resourceFormat, params object[] args) { if (args != null) { if (UsingResourceKeys()) { return resourceFormat + ", " + string.Join(", ", args); } return string.Format(resourceFormat, args); } return resourceFormat; } internal static string Format(IFormatProvider provider, string resourceFormat, object p1) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1); } return string.Format(provider, resourceFormat, p1); } internal static string Format(IFormatProvider provider, string resourceFormat, object p1, object p2) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2); } return string.Format(provider, resourceFormat, p1, p2); } internal static string Format(IFormatProvider provider, string resourceFormat, object p1, object p2, object p3) { if (UsingResourceKeys()) { return string.Join(", ", resourceFormat, p1, p2, p3); } return string.Format(provider, resourceFormat, p1, p2, p3); } internal static string Format(IFormatProvider provider, string resourceFormat, params object[] args) { if (args != null) { if (UsingResourceKeys()) { return resourceFormat + ", " + string.Join(", ", args); } return string.Format(provider, resourceFormat, args); } return resourceFormat; } } } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] internal sealed class AllowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] internal sealed class DisallowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] internal sealed class MaybeNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] internal sealed class NotNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal sealed class MaybeNullWhenAttribute : Attribute { public bool ReturnValue { get; } public MaybeNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal sealed class NotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public NotNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] internal sealed class NotNullIfNotNullAttribute : Attribute { public string ParameterName { get; } public NotNullIfNotNullAttribute(string parameterName) { ParameterName = parameterName; } } [AttributeUsage(AttributeTargets.Method, Inherited = false)] internal sealed class DoesNotReturnAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] internal sealed class DoesNotReturnIfAttribute : Attribute { public bool ParameterValue { get; } public DoesNotReturnIfAttribute(bool parameterValue) { ParameterValue = parameterValue; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] internal sealed class MemberNotNullAttribute : Attribute { public string[] Members { get; } public MemberNotNullAttribute(string member) { Members = new string[1] { member }; } public MemberNotNullAttribute(params string[] members) { Members = members; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] internal sealed class MemberNotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public string[] Members { get; } public MemberNotNullWhenAttribute(bool returnValue, string member) { ReturnValue = returnValue; Members = new string[1] { member }; } public MemberNotNullWhenAttribute(bool returnValue, params string[] members) { ReturnValue = returnValue; Members = members; } } } namespace System.Runtime.InteropServices { [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] internal sealed class LibraryImportAttribute : Attribute { public string LibraryName { get; } public string EntryPoint { get; set; } public StringMarshalling StringMarshalling { get; set; } public Type StringMarshallingCustomType { get; set; } public bool SetLastError { get; set; } public LibraryImportAttribute(string libraryName) { LibraryName = libraryName; } } internal enum StringMarshalling { Custom, Utf8, Utf16 } } namespace System.Formats.Asn1 { public readonly struct Asn1Tag : IEquatable<Asn1Tag> { private const byte ClassMask = 192; private const byte ConstructedMask = 32; private const byte ControlMask = 224; private const byte TagNumberMask = 31; private readonly byte _controlFlags; internal static readonly Asn1Tag EndOfContents = new Asn1Tag((byte)0, 0); public static readonly Asn1Tag Boolean = new Asn1Tag((byte)0, 1); public static readonly Asn1Tag Integer = new Asn1Tag((byte)0, 2); public static readonly Asn1Tag PrimitiveBitString = new Asn1Tag((byte)0, 3); public static readonly Asn1Tag ConstructedBitString = new Asn1Tag(32, 3); public static readonly Asn1Tag PrimitiveOctetString = new Asn1Tag((byte)0, 4); public static readonly Asn1Tag ConstructedOctetString = new Asn1Tag(32, 4); public static readonly Asn1Tag Null = new Asn1Tag((byte)0, 5); public static readonly Asn1Tag ObjectIdentifier = new Asn1Tag((byte)0, 6); public static readonly Asn1Tag Enumerated = new Asn1Tag((byte)0, 10); public static readonly Asn1Tag Sequence = new Asn1Tag(32, 16); public static readonly Asn1Tag SetOf = new Asn1Tag(32, 17); public static readonly Asn1Tag UtcTime = new Asn1Tag((byte)0, 23); public static readonly Asn1Tag GeneralizedTime = new Asn1Tag((byte)0, 24); public TagClass TagClass => (TagClass)(_controlFlags & 0xC0); public bool IsConstructed => (_controlFlags & 0x20) != 0; public int TagValue { get; } private Asn1Tag(byte controlFlags, int tagValue) { _controlFlags = (byte)(controlFlags & 0xE0u); TagValue = tagValue; } public Asn1Tag(UniversalTagNumber universalTagNumber, bool isConstructed = false) : this((byte)(isConstructed ? 32 : 0), (int)universalTagNumber) { if (universalTagNumber < UniversalTagNumber.EndOfContents || universalTagNumber > UniversalTagNumber.RelativeObjectIdentifierIRI || universalTagNumber == (UniversalTagNumber)15) { throw new ArgumentOutOfRangeException("universalTagNumber"); } } public Asn1Tag(TagClass tagClass, int tagValue, bool isConstructed = false) : this((byte)((byte)tagClass | (isConstructed ? 32u : 0u)), tagValue) { switch (tagClass) { default: throw new ArgumentOutOfRangeException("tagClass"); case TagClass.Universal: case TagClass.Application: case TagClass.ContextSpecific: case TagClass.Private: if (tagValue < 0) { throw new ArgumentOutOfRangeException("tagValue"); } break; } } public Asn1Tag AsConstructed() { return new Asn1Tag((byte)(_controlFlags | 0x20u), TagValue); } public Asn1Tag AsPrimitive() { return new Asn1Tag((byte)(_controlFlags & 0xFFFFFFDFu), TagValue); } public static bool TryDecode(ReadOnlySpan<byte> source, out Asn1Tag tag, out int bytesConsumed) { tag = default(Asn1Tag); bytesConsumed = 0; if (source.IsEmpty) { return false; } byte b = source[bytesConsumed]; bytesConsumed++; uint num = b & 0x1Fu; if (num == 31) { num = 0u; byte b2; do { if (source.Length <= bytesConsumed) { bytesConsumed = 0; return false; } b2 = source[bytesConsumed]; byte b3 = (byte)(b2 & 0x7Fu); bytesConsumed++; if (num >= 33554432) { bytesConsumed = 0; return false; } num <<= 7; num |= b3; if (num == 0) { bytesConsumed = 0; return false; } } while ((b2 & 0x80) == 128); if (num <= 30) { bytesConsumed = 0; return false; } if (num > int.MaxValue) { bytesConsumed = 0; return false; } } tag = new Asn1Tag(b, (int)num); return true; } public static Asn1Tag Decode(ReadOnlySpan<byte> source, out int bytesConsumed) { if (TryDecode(source, out var tag, out bytesConsumed)) { return tag; } throw new AsnContentException(System.SR.ContentException_InvalidTag); } public int CalculateEncodedSize() { if (TagValue < 31) { return 1; } if (TagValue <= 127) { return 2; } if (TagValue <= 16383) { return 3; } if (TagValue <= 2097151) { return 4; } if (TagValue <= 268435455) { return 5; } return 6; } public bool TryEncode(Span<byte> destination, out int bytesWritten) { int num = CalculateEncodedSize(); if (destination.Length < num) { bytesWritten = 0; return false; } if (num == 1) { byte b = (byte)(_controlFlags | TagValue); destination[0] = b; bytesWritten = 1; return true; } byte b2 = (byte)(_controlFlags | 0x1Fu); destination[0] = b2; int num2 = TagValue; int num3 = num - 1; while (num2 > 0) { int num4 = num2 & 0x7F; if (num2 != TagValue) { num4 |= 0x80; } destination[num3] = (byte)num4; num2 >>= 7; num3--; } bytesWritten = num; return true; } public int Encode(Span<byte> destination) { if (TryEncode(destination, out var bytesWritten)) { return bytesWritten; } throw new ArgumentException(System.SR.Argument_DestinationTooShort, "destination"); } public bool Equals(Asn1Tag other) { if (_controlFlags == other._controlFlags) { return TagValue == other.TagValue; } return false; } public override bool Equals([NotNullWhen(true)] object? obj) { if (obj is Asn1Tag other) { return Equals(other); } return false; } public override int GetHashCode() { return (_controlFlags << 24) ^ TagValue; } public static bool operator ==(Asn1Tag left, Asn1Tag right) { return left.Equals(right); } public static bool operator !=(Asn1Tag left, Asn1Tag right) { return !left.Equals(right); } public bool HasSameClassAndValue(Asn1Tag other) { if (TagValue == other.TagValue) { return TagClass == other.TagClass; } return false; } public override string ToString() { string text = ((TagClass != 0) ? $"{TagClass}-{TagValue}" : ((UniversalTagNumber)TagValue).ToString()); if (IsConstructed) { return "Constructed " + text; } return text; } } internal static class AsnCharacterStringEncodings { private static readonly UTF8Encoding s_utf8Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true); private static readonly BMPEncoding s_bmpEncoding = new BMPEncoding(); private static readonly IA5Encoding s_ia5Encoding = new IA5Encoding(); private static readonly VisibleStringEncoding s_visibleStringEncoding = new VisibleStringEncoding(); private static readonly NumericStringEncoding s_numericStringEncoding = new NumericStringEncoding(); private static readonly PrintableStringEncoding s_printableStringEncoding = new PrintableStringEncoding(); private static readonly T61Encoding s_t61Encoding = new T61Encoding(); internal static Encoding GetEncoding(UniversalTagNumber encodingType) { return encodingType switch { UniversalTagNumber.UTF8String => s_utf8Encoding, UniversalTagNumber.NumericString => s_numericStringEncoding, UniversalTagNumber.PrintableString => s_printableStringEncoding, UniversalTagNumber.IA5String => s_ia5Encoding, UniversalTagNumber.VisibleString => s_visibleStringEncoding, UniversalTagNumber.BMPString => s_bmpEncoding, UniversalTagNumber.TeletexString => s_t61Encoding, _ => throw new ArgumentOutOfRangeException("encodingType", encodingType, null), }; } internal unsafe static int GetByteCount(this Encoding encoding, ReadOnlySpan<char> str) { if (str.IsEmpty) { str = string.Empty.AsSpan(); } fixed (char* chars = &MemoryMarshal.GetReference(str)) { return encoding.GetByteCount(chars, str.Length); } } internal unsafe static int GetBytes(this Encoding encoding, ReadOnlySpan<char> chars, Span<byte> bytes) { if (chars.IsEmpty) { chars = string.Empty.AsSpan(); } if (bytes.IsEmpty) { bytes = Array.Empty<byte>(); } fixed (char* chars2 = &MemoryMarshal.GetReference(chars)) { fixed (byte* bytes2 = &MemoryMarshal.GetReference(bytes)) { return encoding.GetBytes(chars2, chars.Length, bytes2, bytes.Length); } } } } internal abstract class SpanBasedEncoding : Encoding { protected SpanBasedEncoding() : base(0, System.Text.EncoderFallback.ExceptionFallback, System.Text.DecoderFallback.ExceptionFallback) { } protected abstract int GetBytes(ReadOnlySpan<char> chars, Span<byte> bytes, bool write); protected abstract int GetChars(ReadOnlySpan<byte> bytes, Span<char> chars, bool write); public override int GetByteCount(char[] chars, int index, int count) { return GetByteCount(new ReadOnlySpan<char>(chars, index, count)); } public unsafe override int GetByteCount(char* chars, int count) { return GetByteCount(new ReadOnlySpan<char>(chars, count)); } public override int GetByteCount(string s) { return GetByteCount(s.AsSpan()); } public new int GetByteCount(ReadOnlySpan<char> chars) { return GetBytes(chars, Span<byte>.Empty, write: false); } public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { return GetBytes(new ReadOnlySpan<char>(chars, charIndex, charCount), new Span<byte>(bytes, byteIndex, bytes.Length - byteIndex), write: true); } public unsafe override int GetBytes(char* chars, int charCount, byte* bytes, int byteCount) { return GetBytes(new ReadOnlySpan<char>(chars, charCount), new Span<byte>(bytes, byteCount), write: true); } public override int GetCharCount(byte[] bytes, int index, int count) { return GetCharCount(new ReadOnlySpan<byte>(bytes, index, count)); } public unsafe override int GetCharCount(byte* bytes, int count) { return GetCharCount(new ReadOnlySpan<byte>(bytes, count)); } public new int GetCharCount(ReadOnlySpan<byte> bytes) { return GetChars(bytes, Span<char>.Empty, write: false); } public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { return GetChars(new ReadOnlySpan<byte>(bytes, byteIndex, byteCount), new Span<char>(chars, charIndex, chars.Length - charIndex), write: true); } public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount) { return GetChars(new ReadOnlySpan<byte>(bytes, byteCount), new Span<char>(chars, charCount), write: true); } } internal sealed class IA5Encoding : RestrictedAsciiStringEncoding { internal IA5Encoding() : base(0, 127) { } } internal sealed class VisibleStringEncoding : RestrictedAsciiStringEncoding { internal VisibleStringEncoding() : base(32, 126) { } } internal sealed class NumericStringEncoding : RestrictedAsciiStringEncoding { internal NumericStringEncoding() : base("0123456789 ") { } } internal sealed class PrintableStringEncoding : RestrictedAsciiStringEncoding { internal PrintableStringEncoding() : base("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 '()+,-./:=?") { } } internal abstract class RestrictedAsciiStringEncoding : SpanBasedEncoding { private readonly bool[] _isAllowed; protected RestrictedAsciiStringEncoding(byte minCharAllowed, byte maxCharAllowed) { bool[] array = new bool[128]; array.AsSpan(minCharAllowed, maxCharAllowed - minCharAllowed + 1).Fill(value: true); _isAllowed = array; } protected RestrictedAsciiStringEncoding(string allowedChars) { bool[] array = new bool[127]; foreach (char c in allowedChars) { if (c >= array.Length) { throw new ArgumentOutOfRangeException("allowedChars"); } array[(uint)c] = true; } _isAllowed = array; } public override int GetMaxByteCount(int charCount) { return charCount; } public override int GetMaxCharCount(int byteCount) { return byteCount; } protected override int GetBytes(ReadOnlySpan<char> chars, Span<byte> bytes, bool write) { if (chars.IsEmpty) { return 0; } for (int i = 0; i < chars.Length; i++) { char c = chars[i]; if ((uint)c >= (uint)_isAllowed.Length || !_isAllowed[(uint)c]) { base.EncoderFallback.CreateFallbackBuffer().Fallback(c, i); throw new InvalidOperationException(); } if (write) { bytes[i] = (byte)c; } } return chars.Length; } protected override int GetChars(ReadOnlySpan<byte> bytes, Span<char> chars, bool write) { if (bytes.IsEmpty) { return 0; } for (int i = 0; i < bytes.Length; i++) { byte b = bytes[i]; if ((uint)b >= (uint)_isAllowed.Length || !_isAllowed[b]) { base.DecoderFallback.CreateFallbackBuffer().Fallback(new byte[1] { b }, i); throw new InvalidOperationException(); } if (write) { chars[i] = (char)b; } } return bytes.Length; } } internal sealed class BMPEncoding : SpanBasedEncoding { protected override int GetBytes(ReadOnlySpan<char> chars, Span<byte> bytes, bool write) { if (chars.IsEmpty) { return 0; } int num = 0; for (int i = 0; i < chars.Length; i++) { char c = chars[i]; if (char.IsSurrogate(c)) { base.EncoderFallback.CreateFallbackBuffer().Fallback(c, i); throw new InvalidOperationException(); } ushort num2 = c; if (write) { bytes[num + 1] = (byte)num2; bytes[num] = (byte)(num2 >> 8); } num += 2; } return num; } protected override int GetChars(ReadOnlySpan<byte> bytes, Span<char> chars, bool write) { if (bytes.IsEmpty) { return 0; } if (bytes.Length % 2 != 0) { base.DecoderFallback.CreateFallbackBuffer().Fallback(bytes.Slice(bytes.Length - 1).ToArray(), bytes.Length - 1); throw new InvalidOperationException(); } int num = 0; for (int i = 0; i < bytes.Length; i += 2) { char c = (char)BinaryPrimitives.ReadInt16BigEndian(bytes.Slice(i)); if (char.IsSurrogate(c)) { base.DecoderFallback.CreateFallbackBuffer().Fallback(bytes.Slice(i, 2).ToArray(), i); throw new InvalidOperationException(); } if (write) { chars[num] = c; } num++; } return num; } public override int GetMaxByteCount(int charCount) { return checked(charCount * 2); } public override int GetMaxCharCount(int byteCount) { return byteCount / 2; } } internal sealed class T61Encoding : Encoding { private static readonly UTF8Encoding s_utf8Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true); private static readonly Encoding s_latin1Encoding = Encoding.GetEncoding("iso-8859-1"); public override int GetByteCount(char[] chars, int index, int count) { return s_utf8Encoding.GetByteCount(chars, index, count); } public unsafe override int GetByteCount(char* chars, int count) { return s_utf8Encoding.GetByteCount(chars, count); } public override int GetByteCount(string s) { return s_utf8Encoding.GetByteCount(s); } public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { return s_utf8Encoding.GetBytes(chars, charIndex, charCount, bytes, byteIndex); } public unsafe override int GetBytes(char* chars, int charCount, byte* bytes, int byteCount) { return s_utf8Encoding.GetBytes(chars, charCount, bytes, byteCount); } public override int GetCharCount(byte[] bytes, int index, int count) { try { return s_utf8Encoding.GetCharCount(bytes, index, count); } catch (DecoderFallbackException) { return s_latin1Encoding.GetCharCount(bytes, index, count); } } public unsafe override int GetCharCount(byte* bytes, int count) { try { return s_utf8Encoding.GetCharCount(bytes, count); } catch (DecoderFallbackException) { return s_latin1Encoding.GetCharCount(bytes, count); } } public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { try { return s_utf8Encoding.GetChars(bytes, byteIndex, byteCount, chars, charIndex); } catch (DecoderFallbackException) { return s_latin1Encoding.GetChars(bytes, byteIndex, byteCount, chars, charIndex); } } public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount) { try { return s_utf8Encoding.GetChars(bytes, byteCount, chars, charCount); } catch (DecoderFallbackException) { return s_latin1Encoding.GetChars(bytes, byteCount, chars, charCount); } } public override int GetMaxByteCount(int charCount) { return s_utf8Encoding.GetMaxByteCount(charCount); } public override int GetMaxCharCount(int byteCount) { return byteCount; } } [Serializable] public class AsnContentException : Exception { public AsnContentException() : base(System.SR.ContentException_DefaultMessage) { } public AsnContentException(string? message) : base(message ?? System.SR.ContentException_DefaultMessage) { } public AsnContentException(string? message, Exception? inner) : base(message ?? System.SR.ContentException_DefaultMessage, inner) { } protected AsnContentException(SerializationInfo info, StreamingContext context) : base(info, context) { } } public enum AsnEncodingRules { BER, CER, DER } public static class AsnDecoder { private enum LengthDecodeStatus { NeedMoreData, DerIndefinite, ReservedValue, LengthTooBig, LaxEncodingProhibited, Success } private enum LengthValidity { CerRequiresIndefinite, PrimitiveEncodingRequiresDefinite, LengthExceedsInput, Valid } private delegate void BitStringCopyAction(ReadOnlySpan<byte> value, byte normalizedLastByte, Span<byte> destination); internal const int MaxCERSegmentSize = 1000; internal const int EndOfContentsEncodedLength = 2; public static bool TryReadEncodedValue(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out Asn1Tag tag, out int contentOffset, out int contentLength, out int bytesConsumed) { CheckEncodingRules(ruleSet); if (Asn1Tag.TryDecode(source, out var tag2, out var bytesConsumed2) && TryReadLength(source.Slice(bytesConsumed2), ruleSet, out var length, out var bytesRead)) { int num = bytesConsumed2 + bytesRead; int actualLength; int bytesConsumed3; LengthValidity lengthValidity = ValidateLength(source.Slice(num), ruleSet, tag2, length, out actualLength, out bytesConsumed3); if (lengthValidity == LengthValidity.Valid) { tag = tag2; contentOffset = num; contentLength = actualLength; bytesConsumed = num + bytesConsumed3; return true; } } tag = default(Asn1Tag); contentOffset = (contentLength = (bytesConsumed = 0)); return false; } public static Asn1Tag ReadEncodedValue(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int contentOffset, out int contentLength, out int bytesConsumed) { CheckEncodingRules(ruleSet); int bytesConsumed2; Asn1Tag asn1Tag = Asn1Tag.Decode(source, out bytesConsumed2); int bytesConsumed3; int? encodedLength = ReadLength(source.Slice(bytesConsumed2), ruleSet, out bytesConsumed3); int num = bytesConsumed2 + bytesConsumed3; int actualLength; int bytesConsumed4; LengthValidity lengthValidity = ValidateLength(source.Slice(num), ruleSet, asn1Tag, encodedLength, out actualLength, out bytesConsumed4); if (lengthValidity == LengthValidity.Valid) { contentOffset = num; contentLength = actualLength; bytesConsumed = num + bytesConsumed4; return asn1Tag; } throw GetValidityException(lengthValidity); } private static ReadOnlySpan<byte> GetPrimitiveContentSpan(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, Asn1Tag expectedTag, UniversalTagNumber tagNumber, out int bytesConsumed) { CheckEncodingRules(ruleSet); int bytesConsumed2; Asn1Tag tag = Asn1Tag.Decode(source, out bytesConsumed2); int bytesConsumed3; int? num = ReadLength(source.Slice(bytesConsumed2), ruleSet, out bytesConsumed3); int num2 = bytesConsumed2 + bytesConsumed3; CheckExpectedTag(tag, expectedTag, tagNumber); if (tag.IsConstructed) { throw new AsnContentException(System.SR.Format(System.SR.ContentException_PrimitiveEncodingRequired, tagNumber)); } if (!num.HasValue) { throw new AsnContentException(); } ReadOnlySpan<byte> result = Slice(source, num2, num.Value); bytesConsumed = num2 + result.Length; return result; } private static bool TryReadLength(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int? length, out int bytesRead) { return DecodeLength(source, ruleSet, out length, out bytesRead) == LengthDecodeStatus.Success; } private static int? ReadLength(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int bytesConsumed) { int? length; switch (DecodeLength(source, ruleSet, out length, out bytesConsumed)) { case LengthDecodeStatus.Success: return length; case LengthDecodeStatus.LengthTooBig: throw new AsnContentException(System.SR.ContentException_LengthTooBig); case LengthDecodeStatus.DerIndefinite: case LengthDecodeStatus.LaxEncodingProhibited: throw new AsnContentException(System.SR.ContentException_LengthRuleSetConstraint); default: throw new AsnContentException(); } } private static LengthDecodeStatus DecodeLength(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int? length, out int bytesRead) { length = null; bytesRead = 0; if (source.IsEmpty) { return LengthDecodeStatus.NeedMoreData; } byte b = source[bytesRead]; bytesRead++; if (b == 128) { if (ruleSet == AsnEncodingRules.DER) { bytesRead = 0; return LengthDecodeStatus.DerIndefinite; } return LengthDecodeStatus.Success; } if (b < 128) { length = b; return LengthDecodeStatus.Success; } if (b == byte.MaxValue) { bytesRead = 0; return LengthDecodeStatus.ReservedValue; } byte b2 = (byte)(b & 0xFFFFFF7Fu); if (b2 + 1 > source.Length) { bytesRead = 0; return LengthDecodeStatus.NeedMoreData; } bool flag = ruleSet == AsnEncodingRules.DER || ruleSet == AsnEncodingRules.CER; if (flag && b2 > 4) { bytesRead = 0; return LengthDecodeStatus.LengthTooBig; } uint num = 0u; for (int i = 0; i < b2; i++) { byte b3 = source[bytesRead]; bytesRead++; if (num == 0) { if (flag && b3 == 0) { bytesRead = 0; return LengthDecodeStatus.LaxEncodingProhibited; } if (!flag && b3 != 0 && b2 - i > 4) { bytesRead = 0; return LengthDecodeStatus.LengthTooBig; } } num <<= 8; num |= b3; } if (num > int.MaxValue) { bytesRead = 0; return LengthDecodeStatus.LengthTooBig; } if (flag && num < 128) { bytesRead = 0; return LengthDecodeStatus.LaxEncodingProhibited; } length = (int)num; return LengthDecodeStatus.Success; } private static Asn1Tag ReadTagAndLength(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int? contentsLength, out int bytesRead) { int bytesConsumed; Asn1Tag result = Asn1Tag.Decode(source, out bytesConsumed); int bytesConsumed2; int? num = ReadLength(source.Slice(bytesConsumed), ruleSet, out bytesConsumed2); int num2 = bytesConsumed + bytesConsumed2; if (result.IsConstructed) { if (ruleSet == AsnEncodingRules.CER && num.HasValue) { throw GetValidityException(LengthValidity.CerRequiresIndefinite); } } else if (!num.HasValue) { throw GetValidityException(LengthValidity.PrimitiveEncodingRequiresDefinite); } bytesRead = num2; contentsLength = num; return result; } private static void ValidateEndOfContents(Asn1Tag tag, int? length, int headerLength) { if (tag.IsConstructed || length != 0 || headerLength != 2) { throw new AsnContentException(); } } private static LengthValidity ValidateLength(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, Asn1Tag localTag, int? encodedLength, out int actualLength, out int bytesConsumed) { if (localTag.IsConstructed) { if (ruleSet == AsnEncodingRules.CER && encodedLength.HasValue) { actualLength = (bytesConsumed = 0); return LengthValidity.CerRequiresIndefinite; } } else if (!encodedLength.HasValue) { actualLength = (bytesConsumed = 0); return LengthValidity.PrimitiveEncodingRequiresDefinite; } if (encodedLength.HasValue) { int value = encodedLength.Value; int num = value; if (num > source.Length) { actualLength = (bytesConsumed = 0); return LengthValidity.LengthExceedsInput; } actualLength = value; bytesConsumed = value; return LengthValidity.Valid; } actualLength = SeekEndOfContents(source, ruleSet); bytesConsumed = actualLength + 2; return LengthValidity.Valid; } private static AsnContentException GetValidityException(LengthValidity validity) { return validity switch { LengthValidity.CerRequiresIndefinite => new AsnContentException(System.SR.ContentException_CerRequiresIndefiniteLength), LengthValidity.LengthExceedsInput => new AsnContentException(System.SR.ContentException_LengthExceedsPayload), _ => new AsnContentException(), }; } private static int GetPrimitiveIntegerSize(Type primitiveType) { if (primitiveType == typeof(byte) || primitiveType == typeof(sbyte)) { return 1; } if (primitiveType == typeof(short) || primitiveType == typeof(ushort)) { return 2; } if (primitiveType == typeof(int) || primitiveType == typeof(uint)) { return 4; } if (primitiveType == typeof(long) || primitiveType == typeof(ulong)) { return 8; } return 0; } private static int SeekEndOfContents(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet) { ReadOnlySpan<byte> source2 = source; int num = 0; int num2 = 1; while (!source2.IsEmpty) { int? contentsLength; int bytesRead; Asn1Tag asn1Tag = ReadTagAndLength(source2, ruleSet, out contentsLength, out bytesRead); if (asn1Tag == Asn1Tag.EndOfContents) { ValidateEndOfContents(asn1Tag, contentsLength, bytesRead); num2--; if (num2 == 0) { return num; } } if (!contentsLength.HasValue) { num2++; source2 = source2.Slice(bytesRead); num += bytesRead; } else { ReadOnlySpan<byte> readOnlySpan = Slice(source2, 0, bytesRead + contentsLength.Value); source2 = source2.Slice(readOnlySpan.Length); num += readOnlySpan.Length; } } throw new AsnContentException(); } private static int ParseNonNegativeIntAndSlice(ref ReadOnlySpan<byte> data, int bytesToRead) { int result = ParseNonNegativeInt(Slice(data, 0, bytesToRead)); data = data.Slice(bytesToRead); return result; } private static int ParseNonNegativeInt(ReadOnlySpan<byte> data) { if (Utf8Parser.TryParse(data, out uint value, out int bytesConsumed, '\0') && value <= int.MaxValue && bytesConsumed == data.Length) { return (int)value; } throw new AsnContentException(); } private static ReadOnlySpan<byte> SliceAtMost(ReadOnlySpan<byte> source, int longestPermitted) { return source[..Math.Min(longestPermitted, source.Length)]; } private static ReadOnlySpan<byte> Slice(ReadOnlySpan<byte> source, int offset, int length) { if (length < 0 || source.Length - offset < length) { throw new AsnContentException(System.SR.ContentException_LengthExceedsPayload); } return source.Slice(offset, length); } private static ReadOnlySpan<byte> Slice(ReadOnlySpan<byte> source, int offset, int? length) { if (!length.HasValue) { return source.Slice(offset); } int value = length.Value; if (value < 0 || source.Length - offset < value) { throw new AsnContentException(System.SR.ContentException_LengthExceedsPayload); } return source.Slice(offset, value); } internal static ReadOnlyMemory<byte> Slice(ReadOnlyMemory<byte> bigger, ReadOnlySpan<byte> smaller) { if (smaller.IsEmpty) { return default(ReadOnlyMemory<byte>); } if (bigger.Span.Overlaps(smaller, out var elementOffset)) { return bigger.Slice(elementOffset, smaller.Length); } throw new AsnContentException(); } [Conditional("DEBUG")] private static void AssertEncodingRules(AsnEncodingRules ruleSet) { } internal static void CheckEncodingRules(AsnEncodingRules ruleSet) { if (ruleSet != 0 && ruleSet != AsnEncodingRules.CER && ruleSet != AsnEncodingRules.DER) { throw new ArgumentOutOfRangeException("ruleSet"); } } private static void CheckExpectedTag(Asn1Tag tag, Asn1Tag expectedTag, UniversalTagNumber tagNumber) { if (expectedTag.TagClass == TagClass.Universal && expectedTag.TagValue != (int)tagNumber) { throw new ArgumentException(System.SR.Argument_UniversalValueIsFixed, "expectedTag"); } if (expectedTag.TagClass != tag.TagClass || expectedTag.TagValue != tag.TagValue) { throw new AsnContentException(System.SR.Format(System.SR.ContentException_WrongTag, tag.TagClass, tag.TagValue, expectedTag.TagClass, expectedTag.TagValue)); } } public static bool TryReadPrimitiveBitString(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int unusedBitCount, out ReadOnlySpan<byte> value, out int bytesConsumed, Asn1Tag? expectedTag = null) { if (TryReadPrimitiveBitStringCore(source, ruleSet, expectedTag ?? Asn1Tag.PrimitiveBitString, out var _, out var _, out var unusedBitCount2, out var value2, out var bytesConsumed2, out var normalizedLastByte) && (value2.Length == 0 || normalizedLastByte == value2[value2.Length - 1])) { unusedBitCount = unusedBitCount2; value = value2; bytesConsumed = bytesConsumed2; return true; } unusedBitCount = 0; value = default(ReadOnlySpan<byte>); bytesConsumed = 0; return false; } public static bool TryReadBitString(ReadOnlySpan<byte> source, Span<byte> destination, AsnEncodingRules ruleSet, out int unusedBitCount, out int bytesConsumed, out int bytesWritten, Asn1Tag? expectedTag = null) { if (source.Overlaps(destination)) { throw new ArgumentException(System.SR.Argument_SourceOverlapsDestination, "destination"); } if (TryReadPrimitiveBitStringCore(source, ruleSet, expectedTag ?? Asn1Tag.PrimitiveBitString, out var contentsLength, out var headerLength, out var unusedBitCount2, out var value, out var bytesConsumed2, out var normalizedLastByte)) { if (value.Length > destination.Length) { bytesConsumed = 0; bytesWritten = 0; unusedBitCount = 0; return false; } CopyBitStringValue(value, normalizedLastByte, destination); bytesWritten = value.Length; bytesConsumed = bytesConsumed2; unusedBitCount = unusedBitCount2; return true; } if (TryCopyConstructedBitStringValue(Slice(source, headerLength, contentsLength), ruleSet, destination, !contentsLength.HasValue, out unusedBitCount2, out var bytesRead, out var bytesWritten2)) { unusedBitCount = unusedBitCount2; bytesConsumed = headerLength + bytesRead; bytesWritten = bytesWritten2; return true; } bytesWritten = (bytesConsumed = (unusedBitCount = 0)); return false; } public static byte[] ReadBitString(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int unusedBitCount, out int bytesConsumed, Asn1Tag? expectedTag = null) { if (TryReadPrimitiveBitStringCore(source, ruleSet, expectedTag ?? Asn1Tag.PrimitiveBitString, out var contentsLength, out var headerLength, out var unusedBitCount2, out var value, out var bytesConsumed2, out var normalizedLastByte)) { byte[] array = value.ToArray(); if (value.Length > 0) { array[^1] = normalizedLastByte; } unusedBitCount = unusedBitCount2; bytesConsumed = bytesConsumed2; return array; } int minimumLength = contentsLength ?? SeekEndOfContents(source.Slice(headerLength), ruleSet); byte[] array2 = System.Security.Cryptography.CryptoPool.Rent(minimumLength); if (TryCopyConstructedBitStringValue(Slice(source, headerLength, contentsLength), ruleSet, array2, !contentsLength.HasValue, out unusedBitCount2, out var bytesRead, out var bytesWritten)) { byte[] result = array2.AsSpan(0, bytesWritten).ToArray(); System.Security.Cryptography.CryptoPool.Return(array2, bytesWritten); unusedBitCount = unusedBitCount2; bytesConsumed = headerLength + bytesRead; return result; } throw new AsnContentException(); } private static void ParsePrimitiveBitStringContents(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int unusedBitCount, out ReadOnlySpan<byte> value, out byte normalizedLastByte) { if (ruleSet == AsnEncodingRules.CER && source.Length > 1000) { throw new AsnContentException(System.SR.ContentException_InvalidUnderCer_TryBerOrDer); } if (source.Length == 0) { throw new AsnContentException(); } unusedBitCount = source[0]; if (unusedBitCount > 7) { throw new AsnContentException(); } if (source.Length == 1) { if (unusedBitCount > 0) { throw new AsnContentException(); } value = ReadOnlySpan<byte>.Empty; normalizedLastByte = 0; return; } int num = -1 << unusedBitCount; byte b = source[source.Length - 1]; byte b2 = (byte)(b & num); if (b2 != b && (ruleSet == AsnEncodingRules.DER || ruleSet == AsnEncodingRules.CER)) { throw new AsnContentException(System.SR.ContentException_InvalidUnderCerOrDer_TryBer); } normalizedLastByte = b2; value = source.Slice(1); } private static void CopyBitStringValue(ReadOnlySpan<byte> value, byte normalizedLastByte, Span<byte> destination) { if (value.Length != 0) { value.CopyTo(destination); destination[value.Length - 1] = normalizedLastByte; } } private static int CountConstructedBitString(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, bool isIndefinite) { Span<byte> empty = Span<byte>.Empty; int lastUnusedBitCount; int bytesRead; return ProcessConstructedBitString(source, ruleSet, empty, null, isIndefinite, out lastUnusedBitCount, out bytesRead); } private static void CopyConstructedBitString(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, Span<byte> destination, bool isIndefinite, out int unusedBitCount, out int bytesRead, out int bytesWritten) { bytesWritten = ProcessConstructedBitString(source, ruleSet, destination, CopyBitStringValue, isIndefinite, out unusedBitCount, out bytesRead); } private static int ProcessConstructedBitString(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, Span<byte> destination, BitStringCopyAction copyAction, bool isIndefinite, out int lastUnusedBitCount, out int bytesRead) { lastUnusedBitCount = 0; bytesRead = 0; int num = 1000; ReadOnlySpan<byte> readOnlySpan = source; Stack<(int, int, bool, int)> stack = null; int num2 = 0; Asn1Tag asn1Tag = Asn1Tag.ConstructedBitString; Span<byte> destination2 = destination; while (true) { if (!readOnlySpan.IsEmpty) { asn1Tag = ReadTagAndLength(readOnlySpan, ruleSet, out var contentsLength, out var bytesRead2); if (asn1Tag == Asn1Tag.PrimitiveBitString) { if (lastUnusedBitCount != 0) { throw new AsnContentException(); } if (ruleSet == AsnEncodingRules.CER && num != 1000) { throw new AsnContentException(System.SR.ContentException_InvalidUnderCer_TryBerOrDer); } ReadOnlySpan<byte> source2 = Slice(readOnlySpan, bytesRead2, contentsLength.Value); ParsePrimitiveBitStringContents(source2, ruleSet, out lastUnusedBitCount, out var value, out var normalizedLastByte); int num3 = bytesRead2 + source2.Length; readOnlySpan = readOnlySpan.Slice(num3); bytesRead += num3; num2 += value.Length; num = source2.Length; if (copyAction != null) { copyAction(value, normalizedLastByte, destination2); destination2 = destination2.Slice(value.Length); } continue; } if (!(asn1Tag == Asn1Tag.EndOfContents && isIndefinite)) { if (asn1Tag == Asn1Tag.ConstructedBitString) { if (ruleSet == AsnEncodingRules.CER) { throw new AsnContentException(System.SR.ContentException_InvalidUnderCerOrDer_TryBer); } if (stack == null) { stack = new Stack<(int, int, bool, int)>(); } if (!source.Overlaps(readOnlySpan, out var elementOffset)) { throw new AsnContentException(); } stack.Push((elementOffset, readOnlySpan.Length, isIndefinite, bytesRead)); readOnlySpan = Slice(readOnlySpan, bytesRead2, contentsLength); bytesRead = bytesRead2; isIndefinite = !contentsLength.HasValue; continue; } throw new AsnContentException(); } ValidateEndOfContents(asn1Tag, contentsLength, bytesRead2); bytesRead += bytesRead2; if (stack != null && stack.Count > 0) { (int, int, bool, int) tuple = stack.Pop(); int item = tuple.Item1; int item2 = tuple.Item2; bool item3 = tuple.Item3; int item4 = tuple.Item4; readOnlySpan = source.Slice(item, item2).Slice(bytesRead); bytesRead += item4; isIndefinite = item3; continue; } } if (isIndefinite && asn1Tag != Asn1Tag.EndOfContents) { throw new AsnContentException(); } if (stack == null || stack.Count <= 0) { break; } (int, int, bool, int) tuple2 = stack.Pop(); int item5 = tuple2.Item1; int item6 = tuple2.Item2; bool item7 = tuple2.Item3; int item8 = tuple2.Item4; readOnlySpan = source.Slice(item5, item6).Slice(bytesRead); isIndefinite = item7; bytesRead += item8; } return num2; } private static bool TryCopyConstructedBitStringValue(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, Span<byte> dest, bool isIndefinite, out int unusedBitCount, out int bytesRead, out int bytesWritten) { int num = CountConstructedBitString(source, ruleSet, isIndefinite); if (ruleSet == AsnEncodingRules.CER && num < 1000) { throw new AsnContentException(System.SR.ContentException_InvalidUnderCerOrDer_TryBer); } if (dest.Length < num) { unusedBitCount = 0; bytesRead = 0; bytesWritten = 0; return false; } CopyConstructedBitString(source, ruleSet, dest, isIndefinite, out unusedBitCount, out bytesRead, out bytesWritten); return true; } private static bool TryReadPrimitiveBitStringCore(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, Asn1Tag expectedTag, out int? contentsLength, out int headerLength, out int unusedBitCount, out ReadOnlySpan<byte> value, out int bytesConsumed, out byte normalizedLastByte) { Asn1Tag tag = ReadTagAndLength(source, ruleSet, out contentsLength, out headerLength); CheckExpectedTag(tag, expectedTag, UniversalTagNumber.BitString); ReadOnlySpan<byte> source2 = Slice(source, headerLength, contentsLength); if (tag.IsConstructed) { if (ruleSet == AsnEncodingRules.DER) { throw new AsnContentException(System.SR.ContentException_InvalidUnderDer_TryBerOrCer); } unusedBitCount = 0; value = default(ReadOnlySpan<byte>); normalizedLastByte = 0; bytesConsumed = 0; return false; } ParsePrimitiveBitStringContents(source2, ruleSet, out unusedBitCount, out value, out normalizedLastByte); bytesConsumed = headerLength + source2.Length; return true; } public static bool ReadBoolean(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int bytesConsumed, Asn1Tag? expectedTag = null) { int bytesConsumed2; ReadOnlySpan<byte> primitiveContentSpan = GetPrimitiveContentSpan(source, ruleSet, expectedTag ?? Asn1Tag.Boolean, UniversalTagNumber.Boolean, out bytesConsumed2); if (primitiveContentSpan.Length != 1) { throw new AsnContentException(); } switch (primitiveContentSpan[0]) { case 0: bytesConsumed = bytesConsumed2; return false; default: if (ruleSet == AsnEncodingRules.DER || ruleSet == AsnEncodingRules.CER) { throw new AsnContentException(System.SR.ContentException_InvalidUnderCerOrDer_TryBer); } break; case byte.MaxValue: break; } bytesConsumed = bytesConsumed2; return true; } public static ReadOnlySpan<byte> ReadEnumeratedBytes(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int bytesConsumed, Asn1Tag? expectedTag = null) { return GetIntegerContents(source, ruleSet, expectedTag ?? Asn1Tag.Enumerated, UniversalTagNumber.Enumerated, out bytesConsumed); } public static TEnum ReadEnumeratedValue<TEnum>(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int bytesConsumed, Asn1Tag? expectedTag = null) where TEnum : Enum { Type typeFromHandle = typeof(TEnum); return (TEnum)Enum.ToObject(typeFromHandle, ReadEnumeratedValue(source, ruleSet, typeFromHandle, out bytesConsumed, expectedTag)); } public static Enum ReadEnumeratedValue(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, Type enumType, out int bytesConsumed, Asn1Tag? expectedTag = null) { if (enumType == null) { throw new ArgumentNullException("enumType"); } Asn1Tag expectedTag2 = expectedTag ?? Asn1Tag.Enumerated; Type enumUnderlyingType = enumType.GetEnumUnderlyingType(); if (enumType.IsDefined(typeof(FlagsAttribute), inherit: false)) { throw new ArgumentException(System.SR.Argument_EnumeratedValueRequiresNonFlagsEnum, "enumType"); } int primitiveIntegerSize = GetPrimitiveIntegerSize(enumUnderlyingType); if (enumUnderlyingType == typeof(int) || enumUnderlyingType == typeof(long) || enumUnderlyingType == typeof(short) || enumUnderlyingType == typeof(sbyte)) { if (!TryReadSignedInteger(source, ruleSet, primitiveIntegerSize, expectedTag2, UniversalTagNumber.Enumerated, out var value, out var bytesConsumed2)) { throw new AsnContentException(System.SR.ContentException_EnumeratedValueTooBig); } bytesConsumed = bytesConsumed2; return (Enum)Enum.ToObject(enumType, value); } if (enumUnderlyingType == typeof(uint) || enumUnderlyingType == typeof(ulong) || enumUnderlyingType == typeof(ushort) || enumUnderlyingType == typeof(byte)) { if (!TryReadUnsignedInteger(source, ruleSet, primitiveIntegerSize, expectedTag2, UniversalTagNumber.Enumerated, out var value2, out var bytesConsumed3)) { throw new AsnContentException(System.SR.ContentException_EnumeratedValueTooBig); } bytesConsumed = bytesConsumed3; return (Enum)Enum.ToObject(enumType, value2); } throw new AsnContentException(System.SR.Format(System.SR.Argument_EnumeratedValueBackingTypeNotSupported, enumUnderlyingType.FullName)); } public static DateTimeOffset ReadGeneralizedTime(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int bytesConsumed, Asn1Tag? expectedTag = null) { byte[] rented = null; Span<byte> tmpSpace = stackalloc byte[64]; int bytesConsumed2; ReadOnlySpan<byte> octetStringContents = GetOctetStringContents(source, ruleSet, expectedTag ?? Asn1Tag.GeneralizedTime, UniversalTagNumber.GeneralizedTime, out bytesConsumed2, ref rented, tmpSpace); DateTimeOffset result = ParseGeneralizedTime(ruleSet, octetStringContents); if (rented != null) { System.Security.Cryptography.CryptoPool.Return(rented, octetStringContents.Length); } bytesConsumed = bytesConsumed2; return result; } private static DateTimeOffset ParseGeneralizedTime(AsnEncodingRules ruleSet, ReadOnlySpan<byte> contentOctets) { bool flag = ruleSet == AsnEncodingRules.DER || ruleSet == AsnEncodingRules.CER; if (flag && contentOctets.Length < 15) { throw new AsnContentException(System.SR.ContentException_InvalidUnderCerOrDer_TryBer); } if (contentOctets.Length < 10) { throw new AsnContentException(); } ReadOnlySpan<byte> data = contentOctets; int year = ParseNonNegativeIntAndSlice(ref data, 4); int month = ParseNonNegativeIntAndSlice(ref data, 2); int day = ParseNonNegativeIntAndSlice(ref data, 2); int hour = ParseNonNegativeIntAndSlice(ref data, 2); int? num = null; int? num2 = null; ulong value = 0uL; ulong num3 = 1uL; byte b = byte.MaxValue; TimeSpan? timeSpan = null; bool flag2 = false; byte b2 = 0; while (b2 == 0 && data.Length != 0) { byte? b3 = GetNextState(data[0]); if (!b3.HasValue) { if (!num.HasValue) { num = ParseNonNegativeIntAndSlice(ref data, 2); continue; } if (num2.HasValue) { throw new AsnContentException(); } num2 = ParseNonNegativeIntAndSlice(ref data, 2); } else { b2 = b3.Value; } } if (b2 == 1) { switch (data[0]) { case 44: if (flag) { throw new AsnContentException(System.SR.ContentException_InvalidUnderCerOrDer_TryBer); } break; default: throw new AsnContentException(); case 46: break; } data = data.Slice(1); if (data.IsEmpty) { throw new AsnContentException(); } if (!Utf8Parser.TryParse(SliceAtMost(data, 12), out value, out int bytesConsumed, '\0') || bytesConsumed == 0) { throw new AsnContentException(); } b = (byte)(value % 10); for (int i = 0; i < bytesConsumed; i++) { num3 *= 10; } data = data.Slice(bytesConsumed); uint value2; while (Utf8Parser.TryParse(SliceAtMost(data, 9), out value2, out bytesConsumed, '\0')) { data = data.Slice(bytesConsumed); b = (byte)(value2 % 10); } if (data.Length != 0) { byte? b4 = GetNextState(data[0]); if (!b4.HasValue) { throw new AsnContentException(); } b2 = b4.Value; } } if (b2 == 2) { byte b5 = data[0]; data = data.Slice(1); if (b5 == 90) { timeSpan = TimeSpan.Zero; flag2 = true; } else { bool flag3 = b5 switch { 43 => false, 45 => true, _ => throw new AsnContentException(), }; if (data.IsEmpty) { throw new AsnContentException(); } int hours = ParseNonNegativeIntAndSlice(ref data, 2); int num4 = 0; if (data.Length != 0) { num4 = ParseNonNegativeIntAndSlice(ref data, 2); } if (num4 > 59) { throw new AsnContentException(); } TimeSpan timeSpan2 = new TimeSpan(hours, num4, 0); if (flag3) { timeSpan2 = -timeSpan2; } timeSpan = timeSpan2; } } if (!data.IsEmpty) { throw new AsnContentException(); } if (flag) { if (!flag2 || !num2.HasValue) { throw new AsnContentException(System.SR.ContentException_InvalidUnderCerOrDer_TryBer); } if (b == 0) { throw new AsnContentException(System.SR.ContentException_InvalidUnderCerOrDer_TryBer); } } double num5 = (double)value / (double)num3; TimeSpan timeSpan3 = TimeSpan.Zero; if (!num.HasValue) { num = 0; num2 = 0; if (value != 0L) { timeSpan3 = new TimeSpan((long)(num5 * 36000000000.0)); } } else if (!num2.HasValue) { num2 = 0; if (value != 0L) { timeSpan3 = new TimeSpan((long)(num5 * 600000000.0)); } } else if (value != 0L) { timeSpan3 = new TimeSpan((long)(num5 * 10000000.0)); } try { DateTimeOffset dateTimeOffset = (timeSpan.HasValue ? new DateTimeOffset(year, month, day, hour, num.Value, num2.Value, timeSpan.Value) : new DateTimeOffset(new DateTime(year, month, day, hour, num.Value, num2.Value))); return dateTimeOffset + timeSpan3; } catch (Exception inner) { throw new AsnContentException(System.SR.ContentException_DefaultMessage, inner); } static byte? GetNextState(byte octet) { switch (octet) { case 43: case 45: case 90: return 2; case 44: case 46: return 1; default: return null; } } } public static ReadOnlySpan<byte> ReadIntegerBytes(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int bytesConsumed, Asn1Tag? expectedTag = null) { return GetIntegerContents(source, ruleSet, expectedTag ?? Asn1Tag.Integer, UniversalTagNumber.Integer, out bytesConsumed); } public static BigInteger ReadInteger(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int bytesConsumed, Asn1Tag? expectedTag = null) { int bytesConsumed2; ReadOnlySpan<byte> readOnlySpan = ReadIntegerBytes(source, ruleSet, out bytesConsumed2, expectedTag); byte[] array = System.Security.Cryptography.CryptoPool.Rent(readOnlySpan.Length); BigInteger result; try { byte value = (byte)(((readOnlySpan[0] & 0x80u) != 0) ? byte.MaxValue : 0); array.AsSpan(readOnlySpan.Length, array.Length - readOnlySpan.Length).Fill(value); readOnlySpan.CopyTo(array); array.AsSpan(0, readOnlySpan.Length).Reverse(); result = new BigInteger(array); } finally { System.Security.Cryptography.CryptoPool.Return(array); } bytesConsumed = bytesConsumed2; return result; } public static bool TryReadInt32(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int value, out int bytesConsumed, Asn1Tag? expectedTag = null) { if (TryReadSignedInteger(source, ruleSet, 4, expectedTag ?? Asn1Tag.Integer, UniversalTagNumber.Integer, out var value2, out bytesConsumed)) { value = (int)value2; return true; } value = 0; return false; } [CLSCompliant(false)] public static bool TryReadUInt32(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out uint value, out int bytesConsumed, Asn1Tag? expectedTag = null) { if (TryReadUnsignedInteger(source, ruleSet, 4, expectedTag ?? Asn1Tag.Integer, UniversalTagNumber.Integer, out var value2, out bytesConsumed)) { value = (uint)value2; return true; } value = 0u; return false; } public static bool TryReadInt64(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out long value, out int bytesConsumed, Asn1Tag? expectedTag = null) { return TryReadSignedInteger(source, ruleSet, 8, expectedTag ?? Asn1Tag.Integer, UniversalTagNumber.Integer, out value, out bytesConsumed); } [CLSCompliant(false)] public static bool TryReadUInt64(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out ulong value, out int bytesConsumed, Asn1Tag? expectedTag = null) { return TryReadUnsignedInteger(source, ruleSet, 8, expectedTag ?? Asn1Tag.Integer, UniversalTagNumber.Integer, out value, out bytesConsumed); } private static ReadOnlySpan<byte> GetIntegerContents(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, Asn1Tag expectedTag, UniversalTagNumber tagNumber, out int bytesConsumed) { int bytesConsumed2; ReadOnlySpan<byte> primitiveContentSpan = GetPrimitiveContentSpan(source, ruleSet, expectedTag, tagNumber, out bytesConsumed2); if (primitiveContentSpan.IsEmpty) { throw new AsnContentException(); } if (BinaryPrimitives.TryReadUInt16BigEndian(primitiveContentSpan, out var value)) { ushort num = (ushort)(value & 0xFF80u); if (num == 0 || num == 65408) { throw new AsnContentException(); } } bytesConsumed = bytesConsumed2; return primitiveContentSpan; } private static bool TryReadSignedInteger(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, int sizeLimit, Asn1Tag expectedTag, UniversalTagNumber tagNumber, out long value, out int bytesConsumed) { int bytesConsumed2; ReadOnlySpan<byte> integerContents = GetIntegerContents(source, ruleSet, expectedTag, tagNumber, out bytesConsumed2); if (integerContents.Length > sizeLimit) { value = 0L; bytesConsumed = 0; return false; } long num = (((integerContents[0] & 0x80u) != 0) ? (-1) : 0); for (int i = 0; i < integerContents.Length; i++) { num <<= 8; num |= integerContents[i]; } bytesConsumed = bytesConsumed2; value = num; return true; } private static bool TryReadUnsignedInteger(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, int sizeLimit, Asn1Tag expectedTag, UniversalTagNumber tagNumber, out ulong value, out int bytesConsumed) { int bytesConsumed2; ReadOnlySpan<byte> readOnlySpan = GetIntegerContents(source, ruleSet, expectedTag, tagNumber, out bytesConsumed2); if ((readOnlySpan[0] & 0x80u) != 0) { bytesConsumed = 0; value = 0uL; return false; } if (readOnlySpan.Length > 1 && readOnlySpan[0] == 0) { readOnlySpan = readOnlySpan.Slice(1); } if (readOnlySpan.Length > sizeLimit) { bytesConsumed = 0; value = 0uL; return false; } ulong num = 0uL; for (int i = 0; i < readOnlySpan.Length; i++) { num <<= 8; num |= readOnlySpan[i]; } bytesConsumed = bytesConsumed2; value = num; return true; } public static TFlagsEnum ReadNamedBitListValue<TFlagsEnum>(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int bytesConsumed, Asn1Tag? expectedTag = null) where TFlagsEnum : Enum { Type typeFromHandle = typeof(TFlagsEnum); int bytesConsumed2; TFlagsEnum result = (TFlagsEnum)Enum.ToObject(typeFromHandle, ReadNamedBitListValue(source, ruleSet, typeFromHandle, out bytesConsumed2, expectedTag)); bytesConsumed = bytesConsumed2; return result; } public static Enum ReadNamedBitListValue(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, Type flagsEnumType, out int bytesConsumed, Asn1Tag? expectedTag = null) { if (flagsEnumType == null) { throw new ArgumentNullException("flagsEnumType"); } Type enumUnderlyingType = flagsEnumType.GetEnumUnderlyingType(); if (!flagsEnumType.IsDefined(typeof(FlagsAttribute), inherit: false)) { throw new ArgumentException(System.SR.Argument_NamedBitListRequiresFlagsEnum, "flagsEnumType"); } Span<byte> destination = stackalloc byte[8]; destination = destination[..GetPrimitiveIntegerSize(enumUnderlyingType)]; if (!TryReadBitString(source, destination, ruleSet, out var unusedBitCount, out var bytesConsumed2, out var bytesWritten, expectedTag)) { throw new AsnContentException(System.SR.Format(System.SR.ContentException_NamedBitListValueTooBig, flagsEnumType.Name)); } Enum result; if (bytesWritten == 0) { result = (Enum)Enum.ToObject(flagsEnumType, 0); bytesConsumed = bytesConsumed2; return result; } ReadOnlySpan<byte> valueSpan = destination.Slice(0, bytesWritten); if (ruleSet == AsnEncodingRules.DER || ruleSet == AsnEncodingRules.CER) { byte b = valueSpan[bytesWritten - 1]; byte b2 = (byte)(1 << unusedBitCount); if ((b & b2) == 0) { throw new AsnContentException(System.SR.ContentException_InvalidUnderCerOrDer_TryBer); } } result = (Enum)Enum.ToObject(flagsEnumType, InterpretNamedBitListReversed(valueSpan)); bytesConsumed = bytesConsumed2; return result; } public static BitArray ReadNamedBitList(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int bytesConsumed, Asn1Tag? expectedTag = null) { int contentOffset; int contentLength; int bytesConsumed2; Asn1Tag tag = ReadEncodedValue(source, ruleSet, out contentOffset, out contentLength, out bytesConsumed2); if (expectedTag.HasValue) { CheckExpectedTag(tag, expectedTag.Value, UniversalTagNumber.BitString); } byte[] array = System.Security.Cryptography.CryptoPool.Rent(contentLength); if (!TryReadBitString(source, array, ruleSet, out var unusedBitCount, out var bytesConsumed3, out var bytesWritten, expectedTag)) { throw new InvalidOperationException(); } int length = checked(bytesWritten * 8 - unusedBitCount); Span<byte> value = array.AsSpan(0, bytesWritten); ReverseBitsPerByte(value); BitArray bitArray = new BitArray(array); System.Security.Cryptography.CryptoPool.Return(array, bytesWritten); bitArray.Length = length; bytesConsumed = bytesConsumed3; return bitArray; } private static long InterpretNamedBitListReversed(ReadOnlySpan<byte> valueSpan) { long num = 0L; long num2 = 1L; for (int i = 0; i < valueSpan.Length; i++) { byte b = valueSpan[i]; for (int num3 = 7; num3 >= 0; num3--) { int num4 = 1 << num3; if ((b & num4) != 0) { num |= num2; } num2 <<= 1; } } return num; } internal static void ReverseBitsPerByte(Span<byte> value) { for (int i = 0; i < value.Length; i++) { value[i] = (byte)((ulong)((value[i] * 8623620610L) & 0x10884422010L) % 1023uL); } } public static void ReadNull(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int bytesConsumed, Asn1Tag? expectedTag = null) { if (GetPrimitiveContentSpan(source, ruleSet, expectedTag ?? Asn1Tag.Null, UniversalTagNumber.Null, out var bytesConsumed2).Length != 0) { throw new AsnContentException(); } bytesConsumed = bytesConsumed2; } public static bool TryReadOctetString(ReadOnlySpan<byte> source, Span<byte> destination, AsnEncodingRules ruleSet, out int bytesConsumed, out int bytesWritten, Asn1Tag? expectedTag = null) { if (source.Overlaps(destination)) { throw new ArgumentException(System.SR.Argument_SourceOverlapsDestination, "destination"); } if (TryReadPrimitiveOctetStringCore(source, ruleSet, expectedTag ?? Asn1Tag.PrimitiveOctetString, UniversalTagNumber.OctetString, out var contentLength, out var headerLength, out var contents, out var bytesConsumed2)) { if (contents.Length > destination.Length) { bytesWritten = 0; bytesConsumed = 0; return false; } contents.CopyTo(destination); bytesWritten = contents.Length; bytesConsumed = bytesConsumed2; return true; } int bytesRead; bool flag = TryCopyConstructedOctetStringContents(Slice(source, headerLength, contentLength), ruleSet, destination, !contentLength.HasValue, out bytesRead, out bytesWritten); if (flag) { bytesConsumed = headerLength + bytesRead; } else { bytesConsumed = 0; } return flag; } public static byte[] ReadOctetString(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int bytesConsumed, Asn1Tag? expectedTag = null) { byte[] rented = null; int bytesConsumed2; ReadOnlySpan<byte> octetStringContents = GetOctetStringContents(source, ruleSet, expectedTag ?? Asn1Tag.PrimitiveOctetString, UniversalTagNumber.OctetString, out bytesConsumed2, ref rented); byte[] result = octetStringContents.ToArray(); if (rented != null) { System.Security.Cryptography.CryptoPool.Return(rented, octetStringContents.Length); } bytesConsumed = bytesConsumed2; return result; } private static bool TryReadPrimitiveOctetStringCore(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, Asn1Tag expectedTag, UniversalTagNumber universalTagNumber, out int? contentLength, out int headerLength, out ReadOnlySpan<byte> contents, out int bytesConsumed) { Asn1Tag tag = ReadTagAndLength(source, ruleSet, out contentLength, out headerLength); CheckExpectedTag(tag, expectedTag, universalTagNumber); ReadOnlySpan<byte> readOnlySpan = Slice(source, headerLength, contentLength); if (tag.IsConstructed) { if (ruleSet == AsnEncodingRules.DER) { throw new AsnContentException(System.SR.ContentException_InvalidUnderDer_TryBerOrCer); } contents = default(ReadOnlySpan<byte>); bytesConsumed = 0; return false; } if (ruleSet == AsnEncodingRules.CER && readOnlySpan.Length > 1000) { throw new AsnContentException(System.SR.ContentException_InvalidUnderCer_TryBerOrDer); } contents = readOnlySpan; bytesConsumed = headerLength + readOnlySpan.Length; return true; } public static bool TryReadPrimitiveOctetString(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out ReadOnlySpan<byte> value, out int bytesConsumed, Asn1Tag? expectedTag = null) { int? contentLength; int headerLength; return TryReadPrimitiveOctetStringCore(source, ruleSet, expectedTag ?? Asn1Tag.PrimitiveOctetString, UniversalTagNumber.OctetString, out contentLength, out headerLength, out value, out bytesConsumed); } private static int CountConstructedOctetString(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, bool isIndefinite) { int bytesRead; int num = CopyConstructedOctetString(source, ruleSet, Span<byte>.Empty, write: false, isIndefinite, out bytesRead); if (ruleSet == AsnEncodingRules.CER && num <= 1000) { throw new AsnContentException(System.SR.ContentException_InvalidUnderCerOrDer_TryBer); } return num; } private static void CopyConstructedOctetString(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, Span<byte> destination, bool isIndefinite, out int bytesRead, out int bytesWritten) { bytesWritten = CopyConstructedOctetString(source, ruleSet, destination, write: true, isIndefinite, out bytesRead); } private static int CopyConstructedOctetString(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, Span<byte> destination, bool write, bool isIndefinite, out int bytesRead) { bytesRead = 0; int num = 1000; ReadOnlySpan<byte> readOnlySpan = source; Stack<(int, int, bool, int)> stack = null; int num2 = 0; Asn1Tag asn1Tag = Asn1Tag.ConstructedBitString; Span<byte> destination2 = destination; while (true) { if (!readOnlySpan.IsEmpty) { asn1Tag = ReadTagAndLength(readOnlySpan, ruleSet, out var contentsLength, out var bytesRead2); if (asn1Tag == Asn1Tag.PrimitiveOctetString) { if (ruleSet == AsnEncodingRules.CER && num != 1000) { throw new AsnContentException(System.SR.ContentException_InvalidUnderCerOrDer_TryBer); } ReadOnlySpan<byte> readOnlySpan2 = Slice(readOnlySpan, bytesRead2, contentsLength.Value); int num3 = bytesRead2 + readOnlySpan2.Length; readOnlySpan = readOnlySpan.Slice(num3); bytesRead += num3; num2 += readOnlySpan2.Length; num = readOnlySpan2.Length; if (ruleSet == AsnEncodingRules.CER && num > 1000) { throw new AsnContentException(System.SR.ContentException_InvalidUnderCerOrDer_TryBer); } if (write) { readOnlySpan2.CopyTo(destination2); destination2 = destination2.Slice(readOnlySpan2.Length); } continue; } if (!(asn1Tag == Asn1Tag.EndOfContents && isIndefinite)) { if (asn1Tag == Asn1Tag.ConstructedOctetString) { if (ruleSet == AsnEncodingRules.CER) { throw new AsnContentException(System.SR.ContentException_InvalidUnderCerOrDer_TryBer); } if (stack == null) { stack = new Stack<(int, int, bool, int)>(); } if (!source.Overlaps(readOnlySpan, out var elementOffset)) { throw new AsnContentException(); } stack.Push((elementOffset, readOnlySpan.Length, isIndefinite, bytesRead)); readOnlySpan = Slice(readOnlySpan, bytesRead2, contentsLength); bytesRead = bytesRead2; isIndefinite = !contentsLength.HasValue; continue; } throw new AsnContentException(); } ValidateEndOfContents(asn1Tag, contentsLength, bytesRead2); bytesRead += bytesRead2; if (stack != null && stack.Count > 0) { (int, int, bool, int) tuple = stack.Pop(); int item = tuple.Item1; int item2 = tuple.Item2; bool item3 = tuple.Item3; int item4 = tuple.Item4; readOnlySpan = source.Slice(item, item2).Slice(bytesRead); bytesRead += item4; isIndefinite = item3; continue; } } if (isIndefinite && asn1Tag != Asn1Tag.EndOfContents) { throw new AsnContentException(); } if (stack == null || stack.Count <= 0) { break; } (int, int, bool, int) tuple2 = stack.Pop(); int item5 = tuple2.Item1; int item6 = tuple2.Item2; bool item7 = tuple2.Item3; int item8 = tuple2.Item4; readOnlySpan = source.Slice(item5, item6).Slice(bytesRead); isIndefinite = item7; bytesRead += item8; } return num2; } private static bool TryCopyConstructedOctetStringContents(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, Span<byte> dest, bool isIndefinite, out int bytesRead, out int bytesWritten) { bytesRead = 0; int num = CountConstructedOctetString(source, ruleSet, isIndefinite); if (dest.Length < num) { bytesWritten = 0; return false; } CopyConstructedOctetString(source, ruleSet, dest, isIndefinite, out bytesRead, out bytesWritten); return true; } private static ReadOnlySpan<byte> GetOctetStringContents(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, Asn1Tag expectedTag, UniversalTagNumber universalTagNumber, out int bytesConsumed, ref byte[] rented, Span<byte> tmpSpace = default(Span<byte>)) { if (TryReadPrimitiveOctetStringCore(source, ruleSet, expectedTag, universalTagNumber, out var contentLength, out var headerLength, out var contents, out bytesConsumed)) { return contents; } contents = source.Slice(headerLength); int num = contentLength ?? SeekEndOfContents(contents, ruleSet); if (tmpSpace.Length > 0 && num > tmpSpace.Length) { bool isIndefinite = !contentLength.HasValue; num = CountConstructedOctetString(contents, ruleSet, isIndefinite); } if (num > tmpSpace.Length) { rented = System.Security.Cryptography.CryptoPool.Rent(num); tmpSpace = rented; } if (TryCopyConstructedOctetStringContents(Slice(source, headerLength, contentLength), ruleSet, tmpSpace, !contentLength.HasValue, out var bytesRead, out var bytesWritten)) { bytesConsumed = headerLength + bytesRead; return tmpSpace.Slice(0, bytesWritten); } throw new AsnContentException(); } public static string ReadObjectIdentifier(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int bytesConsumed, Asn1Tag? expectedTag = null) { int bytesConsumed2; ReadOnlySpan<byte> primitiveContentSpan = GetPrimitiveContentSpan(source, ruleSet, expectedTag ?? Asn1Tag.ObjectIdentifier, UniversalTagNumber.ObjectIdentifier, out bytesConsumed2); string result = ReadObjectIdentifier(primitiveContentSpan); bytesConsumed = bytesConsumed2; return result; } private static void ReadSubIdentifier(ReadOnlySpan<byte> source, out int bytesRead, out long? smallValue, out BigInteger? largeValue) { if (source[0] == 128) { throw new AsnContentException(); } byte b = source[0]; int num = ((b >= 136) ? ((b >= 160) ? ((b < 192) ? (-1) : 0) : ((b < 144) ? (-3) : (-2))) : ((b >= 130) ? ((b < 132) ? (-5) : (-4)) : ((b >= 129) ? (-6) : 0))); int num2 = num; int num3 = -1; int i; for (i = 0; i < source.Length; i++) { bool flag = (source[i] & 0x80) == 0; if (!System.LocalAppContextSwitches.AllowAnySizeOid) { num2 += 7; if (num2 > 128) { throw new AsnContentException(System.SR.ContentException_OidTooBig); } } if (flag) { num3 = i; break; } } if (num3 < 0) { throw new AsnContentException(); } bytesRead = num3 + 1; long num4 = 0L; if (bytesRead <= 9) { for (i = 0; i < bytesRead; i++) { byte b2 = source[i]; num4 <<= 7; num4 |= (byte)(b2 & 0x7F); } largeValue = null; smallValue = num4; return; } int num5 = (bytesRead / 8 + 1) * 7; byte[] array = System.Security.Cryptography.CryptoPool.Rent(num5); Array.Clear(array, 0, array.Length); Span<byte> destination = array; Span<byte> destination2 = stackalloc byte[8]; int num6 = bytesRead; i = bytesRead - 8; while (num6 > 0) { byte b3 = source[i]; num4 <<= 7; num4 |= (byte)(b3 & 0x7F); i++; if (i >= num6) { BinaryPrimitives.WriteInt64LittleEndian(destination2, num4); destination2.Slice(0, 7).CopyTo(destination); destination = destination.Slice(7); num4 = 0L; num6 -= 8; i = Math.Max(0, num6 - 8); } } int num7 = array.Length - destination.Length; int num8 = num5 - num7; largeValue = new BigInteger(array); smallValue = null; System.Security.Cryptography.CryptoPool.Return(array, num7); } private static string ReadObjectIdentifier(ReadOnlySpan<byte> contents) { if (contents.Length < 1) { throw new AsnContentException(); } StringBuilder stringBuilder = new StringBuilder((byte)contents.Length * 4); ReadSubIdentifier(contents, out var bytesRead, out var smallValue, out var largeValue); if (smallValue.HasValue) { long num = smallValue.Value; byte value; if (num < 40) { value = 0; } else if (num < 80) { value = 1; num -= 40; } else { value = 2; num -= 80; } stringBuilder.Append(value); stringBuilder.Append('.'); stringBuilder.Append(num); } else { BigInteger value2 = largeValue.Value; byte value = 2; value2 -= (BigInteger)80; stringBuilder.Append(value); stringBuilder.Append('.'); stringBuilder.Append(value2.ToString()); } contents = contents.Slice(bytesRead); int num2 = 62; while (!contents.IsEmpty) { if (!System.LocalAppContextSwitches.AllowAnySizeOid) { if (num2 <= 0) { throw new AsnContentException(System.SR.ContentException_OidTooBig); } num2--; } ReadSubIdentifier(contents, out bytesRead, out smallValue, out largeValue); stringBuilder.Append('.'); if (smallValue.HasValue) { stringBuilder.Append(smallValue.Value); } else { stringBuilder.Append(largeValue.Value.ToString()); } contents = contents.Slice(bytesRead); } return stringBuilder.ToString(); } public static void ReadSequence(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int contentOffset, out int contentLength, out int bytesConsumed, Asn1Tag? expectedTag = null) { int? contentsLength; int bytesRead; Asn1Tag tag = ReadTagAndLength(source, ruleSet, out contentsLength, out bytesRead); CheckExpectedTag(tag, expectedTag ?? Asn1Tag.Sequence, UniversalTagNumber.Sequence); if (!tag.IsConstructed) { throw new AsnContentException(System.SR.Format(System.SR.ContentException_ConstructedEncodingRequired, UniversalTagNumber.Sequence)); } if (contentsLength.HasValue) { if (contentsLength.Value + bytesRead > source.Length) { throw GetValidityException(LengthValidity.LengthExceedsInput); } contentLength = contentsLength.Value; contentOffset = bytesRead; bytesConsumed = contentLength + bytesRead; } else { int num = (contentLength = SeekEndOfContents(source.Slice(bytesRead), ruleSet)); contentOffset = bytesRead; bytesConsumed = num + bytesRead + 2; } } public static void ReadSetOf(ReadOnlySpan<byte> source, AsnEncodingRules ruleSet, out int contentOffset, out int contentLength, out int bytesConsumed, bool skipSortOrderValidation = false, Asn1Tag? expectedTag = null) { int? contentsLength; int bytesRead; Asn1Tag tag = ReadTagAndLength(source, ruleSet, out contentsLength, out bytesRead); CheckExpectedTag(tag, expectedTag ?? Asn1Tag.SetOf, UniversalTagNumber.Set); if (!tag.IsConstructed) { throw new AsnContentException(System.SR.Format(System.SR.ContentException_ConstructedEncodingRequired, UniversalTagNumber.Set)); } int num; ReadOnlySpan<byte> readOnlySpan; if (contentsLength.HasValue) { num = 0; readOnlySpan = Slice(source, bytesRead, contentsLength.Value); } else { int length = SeekEndOfContents(source.Slice(bytesRead), ruleSet); readOnlySpan = Slice(source, bytesRead, length); num = 2; } if (!skipSortOrderValidation && (ruleSet == AsnEncodingRules.DER || ruleSet == AsnEncodingRules.CER)) { ReadOnlySpan<byte> source2 = readOnlySpan; ReadOnlySpan<byte> y = default(ReadOnlySpan<byte>); while (!source2.IsEmpty) { ReadEncodedValue(source2, ruleSet, out var _, out var _, out var bytesConsumed2); ReadOnlySpan<byte> readOnlySpan2 = source2.Slice(0, bytesConsumed2); source2 = source2.Slice(bytesConsumed2); if (SetOfValueComparer.Compare(readOnlySpan2, y) < 0) { throw new AsnContentException(System.SR.ContentE