| File: System\Security\Cryptography\Pkcs\Asn1\RecipientIdentifierAsn.xml.cs | Web Access |
| Project: src\runtime\src\libraries\System.Security.Cryptography.Pkcs\src\System.Security.Cryptography.Pkcs.csproj (System.Security.Cryptography.Pkcs) |
// 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.Pkcs.Asn1 { #if DEBUG file static class ValidateRecipientIdentifierAsn { static ValidateRecipientIdentifierAsn() { var usedTags = new System.Collections.Generic.Dictionary<Asn1Tag, string>(); Action<Asn1Tag, string> ensureUniqueTag = (tag, fieldName) => { if (usedTags.TryGetValue(tag, out string? existing)) { throw new InvalidOperationException($"Tag '{tag}' is in use by both '{existing}' and '{fieldName}'"); } usedTags.Add(tag, fieldName); }; ensureUniqueTag(Asn1Tag.Sequence, "IssuerAndSerialNumber"); ensureUniqueTag(new Asn1Tag(TagClass.ContextSpecific, 0), "SubjectKeyIdentifier"); } [System.Runtime.CompilerServices.MethodImpl( System.Runtime.CompilerServices.MethodImplOptions.NoInlining | System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] internal static void Validate() { } } #endif [StructLayout(LayoutKind.Sequential)] internal partial struct RecipientIdentifierAsn { internal System.Security.Cryptography.Asn1.Pkcs7.IssuerAndSerialNumberAsn? IssuerAndSerialNumber; internal ReadOnlyMemory<byte>? SubjectKeyIdentifier; #if DEBUG static RecipientIdentifierAsn() { ValidateRecipientIdentifierAsn.Validate(); } #endif internal readonly void Encode(AsnWriter writer) { bool wroteValue = false; if (IssuerAndSerialNumber.HasValue) { if (wroteValue) throw new CryptographicException(); IssuerAndSerialNumber.Value.Encode(writer); wroteValue = true; } if (SubjectKeyIdentifier.HasValue) { if (wroteValue) throw new CryptographicException(); writer.WriteOctetString(SubjectKeyIdentifier.Value.Span, new Asn1Tag(TagClass.ContextSpecific, 0)); wroteValue = true; } if (!wroteValue) { throw new CryptographicException(); } } internal static RecipientIdentifierAsn Decode(ReadOnlyMemory<byte> encoded, AsnEncodingRules ruleSet) { try { ValueAsnReader reader = new ValueAsnReader(encoded.Span, ruleSet); DecodeCore(ref reader, encoded, out RecipientIdentifierAsn 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 RecipientIdentifierAsn decoded) { try { DecodeCore(ref reader, rebind, out decoded); } catch (AsnContentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } } private static void DecodeCore(ref ValueAsnReader reader, ReadOnlyMemory<byte> rebind, out RecipientIdentifierAsn decoded) { decoded = default; Asn1Tag tag = reader.PeekTag(); ReadOnlySpan<byte> rebindSpan = rebind.Span; int offset; ReadOnlySpan<byte> tmpSpan; if (tag.HasSameClassAndValue(Asn1Tag.Sequence)) { System.Security.Cryptography.Asn1.Pkcs7.IssuerAndSerialNumberAsn tmpIssuerAndSerialNumber; System.Security.Cryptography.Asn1.Pkcs7.IssuerAndSerialNumberAsn.Decode(ref reader, rebind, out tmpIssuerAndSerialNumber); decoded.IssuerAndSerialNumber = tmpIssuerAndSerialNumber; } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { if (reader.TryReadPrimitiveOctetString(out tmpSpan, new Asn1Tag(TagClass.ContextSpecific, 0))) { decoded.SubjectKeyIdentifier = rebindSpan.Overlaps(tmpSpan, out offset) ? rebind.Slice(offset, tmpSpan.Length) : tmpSpan.ToArray(); } else { decoded.SubjectKeyIdentifier = reader.ReadOctetString(new Asn1Tag(TagClass.ContextSpecific, 0)); } } else { throw new CryptographicException(); } } } }