// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma warning disable SA1028 // ignore whitespace warnings for generated code using System; using System.Formats.Asn1; using System.Runtime.InteropServices; namespace System.Security.Cryptography.Asn1.Pkcs7 { [StructLayout(LayoutKind.Sequential)] internal partial struct ContentInfoAsn { internal string ContentType; internal ReadOnlyMemory<byte> Content; internal readonly void Encode(AsnWriter writer) { Encode(writer, Asn1Tag.Sequence); } internal readonly void Encode(AsnWriter writer, Asn1Tag tag) { writer.PushSequence(tag); try { writer.WriteObjectIdentifier(ContentType); } catch (ArgumentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); try { writer.WriteEncodedValue(Content.Span); } catch (ArgumentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); writer.PopSequence(tag); } internal static ContentInfoAsn Decode(ReadOnlyMemory<byte> encoded, AsnEncodingRules ruleSet) { return Decode(Asn1Tag.Sequence, encoded, ruleSet); } internal static ContentInfoAsn Decode(Asn1Tag expectedTag, ReadOnlyMemory<byte> encoded, AsnEncodingRules ruleSet) { try { ValueAsnReader reader = new ValueAsnReader(encoded.Span, ruleSet); DecodeCore(ref reader, expectedTag, encoded, out ContentInfoAsn decoded); reader.ThrowIfNotEmpty(); return decoded; } catch (AsnContentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } } internal static void Decode(ref ValueAsnReader reader, ReadOnlyMemory<byte> rebind, out ContentInfoAsn decoded) { Decode(ref reader, Asn1Tag.Sequence, rebind, out decoded); } internal static void Decode(ref ValueAsnReader reader, Asn1Tag expectedTag, ReadOnlyMemory<byte> rebind, out ContentInfoAsn decoded) { try { DecodeCore(ref reader, expectedTag, rebind, out decoded); } catch (AsnContentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } } private static void DecodeCore(ref ValueAsnReader reader, Asn1Tag expectedTag, ReadOnlyMemory<byte> rebind, out ContentInfoAsn decoded) { decoded = default; ValueAsnReader sequenceReader = reader.ReadSequence(expectedTag); ValueAsnReader explicitReader; ReadOnlySpan<byte> rebindSpan = rebind.Span; int offset; ReadOnlySpan<byte> tmpSpan; decoded.ContentType = sequenceReader.ReadObjectIdentifier(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); tmpSpan = explicitReader.ReadEncodedValue(); decoded.Content = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray(); explicitReader.ThrowIfNotEmpty(); sequenceReader.ThrowIfNotEmpty(); } } [StructLayout(LayoutKind.Sequential)] internal ref partial struct ValueContentInfoAsn { internal string ContentType; internal ReadOnlySpan<byte> Content; internal readonly void Encode(AsnWriter writer) { Encode(writer, Asn1Tag.Sequence); } internal readonly void Encode(AsnWriter writer, Asn1Tag tag) { writer.PushSequence(tag); try { writer.WriteObjectIdentifier(ContentType); } catch (ArgumentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); try { writer.WriteEncodedValue(Content); } catch (ArgumentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } writer.PopSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); writer.PopSequence(tag); } internal static void Decode(ReadOnlySpan<byte> encoded, AsnEncodingRules ruleSet, out ValueContentInfoAsn decoded) { Decode(Asn1Tag.Sequence, encoded, ruleSet, out decoded); } internal static void Decode(Asn1Tag expectedTag, ReadOnlySpan<byte> encoded, AsnEncodingRules ruleSet, out ValueContentInfoAsn decoded) { try { ValueAsnReader reader = new ValueAsnReader(encoded, ruleSet); DecodeCore(ref reader, expectedTag, out decoded); reader.ThrowIfNotEmpty(); } catch (AsnContentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } } internal static void Decode(scoped ref ValueAsnReader reader, out ValueContentInfoAsn decoded) { Decode(ref reader, Asn1Tag.Sequence, out decoded); } internal static void Decode(scoped ref ValueAsnReader reader, Asn1Tag expectedTag, out ValueContentInfoAsn decoded) { try { DecodeCore(ref reader, expectedTag, out decoded); } catch (AsnContentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } } private static void DecodeCore(scoped ref ValueAsnReader reader, Asn1Tag expectedTag, out ValueContentInfoAsn decoded) { decoded = default; ValueAsnReader sequenceReader = reader.ReadSequence(expectedTag); ValueAsnReader explicitReader; decoded.ContentType = sequenceReader.ReadObjectIdentifier(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); decoded.Content = explicitReader.ReadEncodedValue(); explicitReader.ThrowIfNotEmpty(); sequenceReader.ThrowIfNotEmpty(); } } }